SGA(System Global Area)管理

SGA是一段共享内存区域,包含实例的数据和控制信息,多个用户可以通过这个内存区域共享数据,以避免反复、长时间的从物理磁盘访问数据。

SGA的组成:

Database buffer cache存储在数据库中的数据被查询和修改前,必须将这部分数据从磁盘中读取到buffer cache中,所有用户进程共享访问这部分内存,通常,buffer cache要设置的足够大来避免频繁的磁盘I/O操作。

Shared pool

共享池缓存的用户间的共享信息:

  • 反复调用的SQL 语句。

  • 用户帐户数据、表、索引描述和权限等来自于数据字典的信息。

  • 数据库中储存的过程这类可执行的代码。

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区的工作组成

 wKiom1Ti3Z_SRrGZAAB_B9TkDdE108.gif

通过连接实例查看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