作者:dbtan |【转载时请以超链接形式标明文章出处作者信息】


Oracle 10g 共享池管理的增强:

子缓冲池的分配的算法很简单:
·每个子缓冲池必须满足一定的内存约束;
·每4颗CPU可以分配一个子缓冲池,最多7个。

在Oracle 9i中,每个SubPool至少128MB,在Oracle 10g中,每个子缓冲池至少为265MB。如上篇日志所述,SubPool的数量可以通过_kghdsidx_count参数来控制,但是没有参数可以显示地控制SubPool的大小。

根据以上规则,在一个12颗CPU的系统中,如果分配300MB Shared Pool,Oracle 9i将创建2个SubPool,每个大约150MB,如果共享池增加到500MB,Oracle将创建3个SubPool,每个大约166MB。

不管Oracle 9i中的128MB以及Oracle 10g中的256MB,这样的SubPool在许多复杂的系统中,都可以是过小的,在这些情况下,可能需要增加SubPool的大小。可以通过控制Shared Pool大小以及SubPool的数量来改变SubPool的大小。一些Bug以及内部测试表明500MB的SubPool可能会带来更好的性能,所以从Oracle 11g开始,每个SubPool至少为512MB。

除大小控制之外,在Oracle 10g中,Oracle仍然对共享池的管理做出了进一步改进,那就是对单个子缓冲池进行进一步的细分。现在缺省地,Oracle 10g会将单个缓冲池分割为4个子分区进行管理(这可能是因为通常4颗CPU才分配一个SubPool),使用类似如上的方法在Oracle 10gR2中进行测试:

alter session set events 'immediate trace name heapdump level 2';
alter system set "_kghdsidx_count"=2 scope=spfile;
startup force;
alter session set events 'immediate trace name heapdump level 2';

分析得到的trace文件,当仅有一个子缓冲时,Shared Pool被划分为sga heap(1,0)~sga heap(1,3)一共4个子分区:

[oracle@commserver: ~/admin/ccdb/udump]$grep "sga heap" ccdb_ora_16575.trc
HEAP DUMP heap name="sga heap"  desc=0x2000002c
HEAP DUMP heap name="sga heap(1,0)"  desc=0x2001aae4
HEAP DUMP heap name="sga heap(1,1)"  desc=0x2001b71c
HEAP DUMP heap name="sga heap(1,2)"  desc=0x2001c354
HEAP DUMP heap name="sga heap(1,3)"  desc=0x2001cf8c

当使用两个子缓冲池时,Shared Pool则被划分为8个子分区进行管理:

[oracle@commserver: ~/admin/ccdb/udump]$grep "sga heap" ccdb_ora_17026.trc
HEAP DUMP heap name="sga heap"  desc=0x2000002c
HEAP DUMP heap name="sga heap(1,0)"  desc=0x2001aae4
HEAP DUMP heap name="sga heap(1,1)"  desc=0x2001b71c
HEAP DUMP heap name="sga heap(1,2)"  desc=0x2001c354
HEAP DUMP heap name="sga heap(1,3)"  desc=0x2001cf8c
HEAP DUMP heap name="sga heap(2,0)"  desc=0x2001fbd4
HEAP DUMP heap name="sga heap(2,1)"  desc=0x2002080c
HEAP DUMP heap name="sga heap(2,2)"  desc=0x20021444
HEAP DUMP heap name="sga heap(2,3)"  desc=0x2002207c

通过一个内部表X$KGHLU([K]ernel [G]eneric memory [H]eap manager State of [L]R[U] Of Unpinned Recreatable chunks)可以查询这些子缓冲池的分配:

sys@NEI> select addr,indx,kghluidx,kghludur,kghluops,kghlurcr from x$kghlu;

ADDR           INDX   KGHLUIDX   KGHLUDUR   KGHLUOPS   KGHLURCR
-------- ---------- ---------- ---------- ---------- ----------
B724605C          0          2          3       3694        153
B7245C54          1          2          2       3345        416
B5B8E320          2          2          1       6046       1055
B5B8DF18          3          2          0          0          0
B5B8DB10          4          1          3      13015        126
B72E754C          5          1          2       7347        374
B72E7144          6          1          1       2974        610
B72E6D3C          7          1          0          0          0

8 rows selected.

通过这一系统的算法改进,Oracle中Shared Pool管理得以不断增强,较好地解决了大Shared Pool的性能问题;Oracle 8i中,过大Shared Pool设置可能带来的闩锁争用等性能问题在某种程度上得以解决。从Oracle 10g开始,Oracle开始提供自动共享内存管理(ASMM),使用该特性,用户可以不必显示设置共享内存参数,Oracle会自动进行分配和调整,虽然Oracle给我们提供了极大的便利,但是了解自动化后面的原理对于理解Oracle的运行机制仍然是十分重要的。

- The End -