从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,以提高并发性,减少竞争。
Shared Pool的每个SubPool可以被看作是一个Mini Shared Pool,拥有自己独立的Free List,内存结构以及LRU List.同时Oracle提供多个Latch对各个
子缓冲池进行管理,从而避免单个Latch的竞争(Shared Pool Reserved Area同样进行分割管理)。SubPool最多可以有7个,Shared Pool Latch
也从原来的一个增加到现在的7个.如果系统有4个或4个以上的CPU,并且SHARED_POOL_SIZE大于250MB,Oracle可以把Shared Pool分割为多个
缓冲池(SubPool)进行管理.在Oracle 9i
如果你看到类似如下信息,那就意味着你可能遇到了SubPool的问题:
Tue
Error in file /oracle .../..trc
ORA-04301:unable to allocate 4216bytes of shared memory
("shared pool","IDX_...","sga heap(2,0)","library cache")
ORA-04301:unable to allocate 4216 bytes of shared memory
("shared pool","IDX...","sga heap(2,0)","library cache");
子缓冲池的数量受一个新引入的隐含参数_KGHDSIDX_COUNT影响。可以手工调整该参数(仅限于试验环境研究用),观察共享池管理的变化,
可以通过如下步骤转储默认情况以及修改后的Shared Pool,再进行观察:
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 3';
以下是概要输出,注意在前者的跟踪文件中,sga heap(1,0)指共享池只存在一个子缓冲,后者则存在sga heap(1,0)级及sga heap(2,0)两个子缓冲池:
grep "sga heap" eygle_ora_24..trc
HEAP DUMP heap name="sga heap" desc=0x...
HEAP DUMP heap name="sga heap(1,0)" desc=0x..
子缓冲池分配的算法很简单:
*每个子缓冲必须满足一定的内存约束条件
*每4颗CPU可以分配一个子缓冲,子缓冲的数量最多7个
通过一个内部表X$KGHLU
SQL>select addr,indx,kghluidx,kghludur,kghluops,kghlurce from x$kghlu;
通过一系列的算法改进,Oracle中Shared Pool管理得以不断增加,较好地解决了大Shared Pool的性能问题:Oracle 8i中,过大Shared Pool设置
可能带来栓锁争用等性能问题在某种程序上得以解决。从Oracle 10g开始,Oracle开始提供自动共享内存管理,使用该特性,用户可以不必显示共享
内存参数,Oracle会自动进行分配和调整,虽然Oracle为用户提供了极大的便利,但是了解自动化后面的原理对于理解Oracle的运行机制仍然十分重要。
虽然多缓冲池技术使Oracle可以管理更大的共享池,但是SubPool的划分可能也会导致各分区之间的协调问题,甚至可能因为内在分散而出现
ORA-04301错误。最常见的问题是某个子缓冲池(subpool)可能出现过度使用,当新的进程仍然被分配到这个Subpool时,可能会导致内存请求失败,
而此进其他subpool可能还有很多内在空间
因为子缓冲池存在的种种问题,从oracle 10g开始,允许内存请求在不同subpool之间进行切换(switch),从而提高了请求成功的可能(但是显示切换
不可能是无限制的,所以问题仍然可能存在)