Oracle 9i 子缓冲池的增强:
从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,每个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,Oralce可以把Shared Pool分割为多个子缓冲池(SubPool)进行管理,在Oracle 9i中,每个SubPool至少128MB。 以下查询显示的是为管理SubPool而新增的子Latch:
sys@NEI> col name for a30 sys@NEI> select addr,name,gets,misses,spin_gets from v$latch_children where name='shared pool'; ADDR NAME GETS MISSES SPIN_GETS -------- ------------------------------ ---------- ---------- ---------- 20096270 shared pool 9323513 5026 4444 200962D4 shared pool 64 0 0 20096338 shared pool 64 0 0 2009639C shared pool 64 0 0 20096400 shared pool 64 0 0 20096464 shared pool 64 0 0 200964C8 shared pool 64 0 0 已选择7行。
子缓冲的数量受一个新引入的隐含参数_KGHDSIDX_COUNT影响。可以手工调整该参数(仅限于试验环境研究用),观察共享池管理的变化:
sys@NEI> alter system set "_kghdsidx_count"=2 scope=spfile; 系统已更改。 sys@NEI> col KSPPINM for a20 sys@NEI> col KSPPSTVL for a20 sys@NEI> select a.ksppinm,b.ksppstvl from x$ksppi a,x$ksppsv b where a.indx=b.indx and a.ksppinm='_kghdsidx_count'; KSPPINM KSPPSTVL -------------------- -------------------- _kghdsidx_count 2 sys@NEI> col name for a20 sys@NEI> select addr,name,gets,misses,spin_gets from v$latch_children where name='shared pool'; ADDR NAME GETS MISSES SPIN_GETS -------- -------------------- ---------- ---------- ---------- 20096270 shared pool 31947 13 13 200962D4 shared pool 25951 16 16 20096338 shared pool 8 0 0 2009639C shared pool 8 0 0 20096400 shared pool 8 0 0 20096464 shared pool 8 0 0 200964C8 shared pool 8 0 0 已选择7行。
通过如下步骤转储缺省情况以及修改后的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 2';
注意前者的跟踪文件中,sga heap(1,0) 指共享池只存在一个子缓冲,后者则存在sga heap(1,0)以及sga heap(2,0)两个子缓冲池。
但是需要注意的是,虽然多缓冲池技术使Oracle可以管理更大的共享池,但是SubPool的划分可能也会导致各分区之间的协调问题,甚至可能因为内存分散而出现 ORA-04031 错误。最常见的问题是某个子缓冲池(SubPool)可能出现过度使用,当新的进程仍然被分配到这个SubPool时,可能会导致内存请求失败(而此时其他SubPool可能还有很多内存空间)。在具体诊断中可以通过如下SQL查询数据库各缓冲池的自由内存空间数量(10g摘要信息):
sys@NEI> select KSMCHIDX "SubPool",'sga heap('||KSMCHIDX||',0)' sga_heap,ksmchcom ChunkComment, 2 decode(round(ksmchsiz/1000),0,'0-1K',1,'1-2K',2,'2-3K',3,'3-4K', 3 4,'4-5K',5,'5-6K',6,'6-7K',7,'7-8K',8,'8-9K',9,'9-10K','> 10K') "size", 4 count(*) ,ksmchcls Status, sum(ksmchsiz) Bytes 5 from x$ksmsp where KSMCHCOM = 'free memory' group by ksmchidx,ksmchcls, 6 'sga heap('||KSMCHIDX||',0)',ksmchcom,ksmchcls,decode(round(ksmchsiz/1000),0,'0-1K', 7 1,'1-2K',2,'2-3K',3,'3-4K',4,'4-5K',5,'5-6K',6, 8 '6-7K',7,'7-8K',8,'8-9K',9,'9-10K','> 10K') 9 order by 1; SubPool SGA_HEAP CHUNKCOMMENT size COUNT(*) STATUS BYTES ---------- ------------------ ---------------- ----- ---------- -------- ---------- 1 sga heap(1,0) free memory 8-9K 2 free 16332 1 sga heap(1,0) free memory 0-1K 150 free 14076 1 sga heap(1,0) free memory 2-3K 1 free 1920 1 sga heap(1,0) free memory 1-2K 18 free 16464 1 sga heap(1,0) free memory 4-5K 24 free 96336 1 sga heap(1,0) free memory > 10K 7 free 6648696 1 sga heap(1,0) free memory 3-4K 6 free 18756 1 sga heap(1,0) free memory > 10K 10 R-free 2128880 2 sga heap(2,0) free memory > 10K 10 free 4819220 2 sga heap(2,0) free memory 1-2K 6 free 5004 2 sga heap(2,0) free memory > 10K 11 R-free 2341768 2 sga heap(2,0) free memory 2-3K 1 free 2032 2 sga heap(2,0) free memory 4-5K 12 free 46936 2 sga heap(2,0) free memory 0-1K 85 free 8284 14 rows selected.
因为子缓冲池存在的种种问题,从Oracle 10g开始,Oracle允许内存请求在不同SubPool之间进行切换(Switch),从而提高了请求成功的可能(但是显然切换不可能是无限制的,所以问题仍然可能存在)。
- The End -