SGA(System Global Area)管理
SGA是一段共享内存区域,包含实例的数据和控制信息,多个用户可以通过这个内存区域共享数据,以避免反复、长时间的从物理磁盘访问数据。
SGA的组成:
Database buffer cache | 存储在数据库中的数据被查询和修改前,必须将这部分数据从磁盘中读取到buffer cache中,所有用户进程共享访问这部分内存,通常,buffer cache要设置的足够大来避免频繁的磁盘I/O操作。 |
Shared pool |
共享池缓存的用户间的共享信息:
|
Redo log buffer |
在redo信息可以被写回到物理的online redo log 文件之前,通过该buffer缓存这些信息来改善性能。 |
Large pool |
这个可选区域用于缓存各种服务进程中较大的I/O请求。 |
Java pool |
Java池用于JVM(Java Virtual Machine)中的Java代码和数据等特定会话。 |
Streams pool |
流池用于Oracle的流功能。 |
Result cache |
结果缓存缓存着查询的结果,如果一个查询执行的结果在该缓存中存在,数据库通过直接返回该结果来取代重新执行查询语句。这个组成部分用用于加速查询执行的频率。 |
通过下图展示SGA区的工作组成
通过连接实例查看SGA分配情况
SQL> show sga; Total System Global Area 6680915968 bytes Fixed Size 2213936 bytes Variable Size 2550138832 bytes Database Buffers 4093640704 bytes Redo Buffers 34922496 bytes
首先,分别解释SGA组成部分
Database Buffer Cache:
在9i之前该部分的大小主要由以下两个参数决定,db_block_buffers的值表示为分配给buffer cache的缓存块数量,db_block_size表示buffer cache的一个块的大小。
SQL> show parameter db_block NAME TYPE VALUE ---------------- ------------- ------------------------------ db_block_buffers integer 0 db_block_size integer 8192
因此,如果db_block_buffers的值不为0,那么Database buffer cache=db_block_buffers*db_block_size。Oracle后续引入一个新的初始化参数db_cache_size。该参数定义db_block_size的默认缓冲池的大小。
db_cache_size最小值为一个粒度(Granule)。粒度也是9i引入的一个概念,是连续虚拟内存的分配单位。其大小取决于SGA估计的总大小,SGA总大小由SGA_MAX_SIZE参数设定。
修改SGA_MAX_SIZE的大小(本实验时在11.2.0.1.0下进行测试的)
SQL> alter system set sga_max_size=1G scope=spfile; SQL> show parameter db_cache_size NAME TYPE VALUE ------------------------ ----------- ------------------------------ db_cache_size big integer 24M SQL> @getparDescr.sql Enter value for get_parameters: _ksmg_granule_size old 10: and ksppinm like '&get_parameters%' new 10: and ksppinm like '_ksmg_granule_size%' NAME TYPE VALUE VALUE DEFAULTS DESCRIBE KSPPIHASH -------------------- ---------- --------------- --------------- --------- ------------------------------ ---------- _ksmg_granule_size 3 4194304 4194304 TRUE granule size in bytes 4165852122
从1G修改成2G可以看到粒度发生改变
SQL> alter system set sga_max_size=2G scope=spfile; SQL> @getparDescr.sql Enter value for get_parameters: _ksmg_granule_size old 10: and ksppinm like '&get_parameters%' new 10: and ksppinm like '_ksmg_granule_size%' NAME TYPE VALUE VALUE DEFAULTS DESCRIBE KSPPIHASH -------------------- ---------- --------------- --------------- --------- ------------------------------ ---------- _ksmg_granule_size 3 16777216 16777216 TRUE granule size in bytes 4165852122 SQL> show parameter db_cache_size NAME TYPE VALUE ------------------ ----------- ------------------------------ db_cache_size big integer 32M
@getparDescr.sql脚本
set line 300 col name for a20 col value for a15 col describe for a30 col ksspihash for a15 select ksppinm name, ksppity type, ksppstvl value, ksppstdvl value, ksppstdf defaults, ksppdesc describe, ksppihash from x$ksppi x, x$ksppcv y where x.indx = y.indx and ksppinm like '&get_parameters%';
Oracle管理Buffer Cache使用LRU算法,但同时也有问题,全表扫描等操作时可能会导致buffer cache的刷新,将经常用的数据刷出buffer cache。Oracle除了在不同版本中修改LRU算法,来避免此类问题的发生外,还提供了Buffer Cache的多缓冲池技术从另一方面来解决这个问题。
所谓多缓冲池技术,即通过不同的访问方式来访问不同的数据。
将buffer cache分为default,keep,recycle池三个部分。对于常用的数据,可以在建表时就指定将其存放在keep池中;对于一次性读取的数据,可以将其存放在recycle池中。而dafualt存放未指定的存储池的数据。
如果在创建表和修改表的时,指定storage(buffer_pool keep)或storage(buffer_pool recycle)语句,那么这张表就使用keep或recycle缓冲区。这两个缓冲区大小由初始化参数db_keep_cache_size和db_recycle_cache_size决定。
SQL> show parameter cache_size; NAME TYPE VALUE --------------------------- ----------- ------------------------------ client_result_cache_size big integer 0 db_16k_cache_size big integer 0 db_2k_cache_size big integer 0 db_32k_cache_size big integer 0 db_4k_cache_size big integer 0 db_8k_cache_size big integer 0 db_cache_size big integer 64M db_flash_cache_size big integer 0 db_keep_cache_size big integer 0 db_recycle_cache_size big integer 0 SQL> alter system set db_keep_cache_size=64M scope=both; SQL> alter system set db_recycle_cache_size=64M scope=both SQL> show parameter cache_size; NAME TYPE VALUE --------------------- ----------- ------------------------------ db_cache_size big integer 64M db_flash_cache_size big integer 0 db_keep_cache_size big integer 64M db_recycle_cache_size big integer 64M
另外可以看到还有很多db_nk_cache_size这类形式的参数,Oracle支持多种块大小。即不同的表空间可以由多种块大小。而db_block_size定义的块大小为数据库的默认块大小,该值是不建议也不要去修改的。
通过v$buffer_pool视图获取当前buffer池的分配信息:
SQL> select id,name block_size,current_size,target_size from v$buffer_pool; ID BLOCK_SIZE CURRENT_SIZE TARGET_SIZE ---------- -------------------- ------------ ----------- 1 KEEP 64 64 2 RECYCLE 64 64 3 DEFAULT 2688 2688
Shared Pool:
该池大小由参数shared_pool_size定义
SQL> show parameter shared_pool NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ shared_pool_reserved_size big integer 46976204 shared_pool_size big integer 0 SQL> select component,current_size,min_size,granule_size from v$sga_dynamic_components where component='shared pool'; COMPONENT CURRENT_SIZE MIN_SIZE GRANULE_SIZE ------------ ------------ ---------- ------------ shared pool 939524096 939524096 67108864
Redo Log Buffer:
该大小由log_buffer参数决定
SQL> show parameter log_buffer; NAME TYPE VALUE -------------------- ----------- ------------ log_buffer integer 33472512
Large Pool:
其大小由large_pool_size决定,通过v$sga_dynamic_components也能到当前的大小
SQL> show parameter large_pool_size NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ large_pool_size big integer 0 SQL> select component,current_size,min_size,granule_size from v$sga_dynamic_components where component='large pool'; COMPONENT CURRENT_SIZE MIN_SIZE GRANULE_SIZE ---------- ------------ ---------- ------------ large pool 67108864 67108864 67108864
Java Pool:
用于JVM(Java Vitural Machine)的java组件。
SQL> show parameter java_pool NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ java_pool_size big integer 0 SQL> select component,current_size,min_size,granule_size from v$sga_dynamic_components where component='java pool'; COMPONENT CURRENT_SIZE MIN_SIZE GRANULE_SIZE ------------------------------ ------------ ---------- ------------ java pool 67108864 67108864 67108864
Streams Pool:
因为Oracle的参数没有定义值,所以这部分内存从Shared Pool中分配。
SQL> show parameter stream NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ streams_pool_size big integer 0 SQL> select component,current_size,min_size,granule_size from v$sga_dynamic_components where component='streams pool'; COMPONENT CURRENT_SIZE MIN_SIZE GRANULE_SIZE ------------------------------ ------------ ---------- ------------ streams pool 0 0 67108864
Oracle 9i以后通过设定sga_max_size来决定SGA的总大小。
SQL> show parameter sga_max_size NAME TYPE VALUE -------------- ----------- ------------------------------ sga_max_size big integer 6464M
我们再回过头来看一下ORACLE SGA分类:
SQL> show sga Total System Global Area 6747725824 bytes Fixed Size 2213976 bytes Variable Size 3758098344 bytes Database Buffers 2952790016 bytes Redo Buffers 34623488 bytes
Oracle把SGA分成固定大小(Fixed Size),变动大小(Variable Size),数据库缓冲区(Database Buffers)及Redo缓冲(Redo Buffers)。
SQL> select component,current_size,min_size,granule_size from v$sga_dynamic_components; COMPONENT CURRENT_SIZE MIN_SIZE GRANULE_SIZE ------------------------------ ------------ ---------- ------------ shared pool 939524096 939524096 67108864 large pool 67108864 67108864 67108864 java pool 67108864 67108864 67108864 streams pool 0 0 67108864 DEFAULT buffer cache 2818572288 2818572288 67108864 KEEP buffer cache 67108864 0 67108864 RECYCLE buffer cache 67108864 0 67108864 SQL> select 2818572288+67108864*2 from dual; 2818572288+67108864*2 --------------------- 2952790016
从这个看出,Database Buffers包括DEFAULT buffer cache,KEEP buffer cache,RECYCLE buffer cache,DEFAULT nK buffer cache等组成。
而变动部分(Variable Size)=(Total SGA) - (Database Buffers) - (Redo Buffers) - (Fixed Size) 。Shared pool,large pool,java pool都属于这个部分中的。
也可以通过v$sgastat来查看更详细的sga组成:
SQL> select * from v$sgastat where rownum < 50; POOL NAME BYTES ------------ -------------------------- ---------- fixed_sga 2213976 buffer_cache 2952790016 log_buffer 34623488 shared pool dpslut_kfdsg 512 shared pool ENQUEUE STATS 20952 shared pool transaction 681560 shared pool Wait History Array 8 shared pool vproblem_bucket 848 shared pool vnot_exist_incident 3200 shared pool KCB buffer wait statistic 3352 shared pool KCB tablespace encryption 1088 shared pool invalid low rba queue 4096 shared pool bt_qentry 28512 shared pool v_ipsprbcnt 664 shared pool vproblem_int 2448 shared pool PLDIA 3704360 shared pool PRTDS 572264 shared pool DISPATCHERS INFO 2496 shared pool CCUR 9454816 shared pool SQLA 35923048 shared pool plwpil:wa 4264 shared pool kelt translation table 336 shared pool kglsim recovery area 3168 shared pool ksdhng: blkers cache 7936 shared pool procs_kfgbsg 1936 shared pool service names array 16 shared pool SHARED SERVERS INFO 3672 shared pool ASH buffers 16252928 shared pool PMON blockers 1984 shared pool sga listelement 2048 shared pool vproblem 2728 shared pool peshm.c:latch 160 shared pool cp srv array 3024 shared pool obj stats hash table 672 shared pool Managed Standby Proc Arra 28672 shared pool KSIR SGA 144 shared pool KGKP sga 40 shared pool BRANCH TABLE SEGMENTED AR 211720 shared pool SAGE commit cache node Al 22528 shared pool osp pool handles 8 shared pool pesom.c:subheap ds array 2024 shared pool SGA - SWRF Time Model Bas 112 shared pool Service-level trace setti 536 shared pool sys event stats for Other 35776 shared pool LRMPD SGA Table 268688 shared pool namhsh_kfgsg 288 shared pool msg Q child latches 896 SQL> select sum(bytes) from v$sgastat where pool='shared pool'; SUM(BYTES) ---------- 939528904 SQL> select * from v$sgainfo; NAME BYTES RES -------------------------------- ---------- --- Fixed SGA Size 2213976 No Redo Buffers 34623488 No Buffer Cache Size 2952790016 Yes Shared Pool Size 939524096 Yes Large Pool Size 67108864 Yes Java Pool Size 67108864 Yes Streams Pool Size 0 Yes Shared IO Pool Size 0 Yes Granule Size 67108864 No Maximum SGA Size 6747725824 No Startup overhead in Shared Pool 134217728 No Free SGA Memory Available 2684354560
不过这里展示的shared pool大小与Shared Pool Size大小有一些出入,书中说共享池内存在分配和使用过程中会存在一定量的额外消耗,这部分内存被单独列出来查看v$sgainfo中的Startup overhead in Shared Pool