oracle中sga相关的共享池策略(9i以后)

共享池的改进与ORA-04031的变化

我们知道,从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至少为128MB。

如果你看到过类似如下信息,那就意味着你可能遇到了SubPool的问题,如下所示:

 
 
  1. Tue Dec 11 17:14:49 2007  
  2.  
  3. Errors in file  
  4. /oracle/app/admin/ctais2/udump/ctais2_ora_778732.trc:  
  5. ORA-04031: unable to allocate 4216 bytes of shared memory  
  6. ("shared pool","IDX_DJ_NSRXX_P_NSRMCCTAIS2","sga  
  7. heap(2,0)","library cache")  
  8. ORA-04031: unable to allocate 4216 bytes of shared memory  
  9. ("shared pool","IDX_DJ_NSRXX_P_NSRMCCTAIS2","sga  
  10. heap(2,0)","library cache")  
  11. Tue Dec 11 17:14:51 2007  
  12. Errors in file  
  13. /oracle/app/admin/ctais2/bdump/ctais2_pmon_393248.trc:  
  14. ORA-04031: unable to allocate 4216 bytes of shared memory  
  15. ("shared pool","unknown object","sga heap(2,0)","library  
  16. cache") 
Oracle 9i中多个子缓冲池的结构如图1-19所示。
 
子缓冲池的数量受一个新引入的隐含参数_KGHDSIDX_COUNT影响。可以手工调整该参数(仅限于试验环境研究用),观察共享池管理的变化,可以通过如下步骤转储默认情况以及修改后的Shared Pool,再进行观察:
 
 
  1. alter session set events 'immediate trace name   
  2. heapdump level 2';   
  3. alter system set "_kghdsidx_count"=2 scope=spfile;  
  4. startup force;  
  5. alter session set events 'immediate trace name   
  6. heapdump level 2'; 

以下是概要输出,注意在前者的跟踪文件中,sga heap(1,0)指共享池只存在一个子缓冲,后者则存在sga heap(1,0)以及sga heap(2,0)两个子缓冲池:

 
 
  1. [oracle@jumper udump]$ grep "sga heap" eygle_ora_25766.trc  
  2. HEAP DUMP heap name="sga heap"  desc=0x5000002c  
  3. HEAP DUMP heap name="sga heap(1,0)"  desc=0x5001ef0c  
  4. [oracle@jumper udump]$ grep "sga heap" eygle_ora_25786.trc   
  5. HEAP DUMP heap name="sga heap"  desc=0x5000002c  
  6. HEAP DUMP heap name="sga heap(1,0)"  desc=0x5001ef0c  
  7. HEAP DUMP heap name="sga heap(2,0)"  desc=0x50023c04 

子缓冲池分配的算法很简单:

每个子缓冲池必须满足一定的内存约束条件;

每4颗CPU可以分配一个子缓冲池,子缓冲池的数量最多7个。

在Oracle 9i中,每个SubPool容量至少128MB,而在Oracle 10g中,每个子缓冲池容量至少为256MB。如前所述,SubPool的数量可以通过_KGHDSIDX_COUNT参数来控制,但是没有参数可以显式地控制SubPool的大小。

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

不管是Oracle 9i中的128MB,还是Oracle10g中的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中进行测试:

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

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

 
 
  1. [oracle@eygle udump]$ grep "sga heap" eygle_ora_13577.trc  
  2. HEAP DUMP heap name="sga heap"  desc=0x2000002c  
  3. HEAP DUMP heap name="sga heap(1,0)"  desc=0x2001b550  
  4. HEAP DUMP heap name="sga heap(1,1)"  desc=0x2001c188  
  5. HEAP DUMP heap name="sga heap(1,2)"  desc=0x2001cdc0  
  6. HEAP DUMP heap name="sga heap(1,3)"  desc=0x2001d9f8 

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

 
 
  1. [oracle@eygle udump]$ grep "sga heap" eygle_ora_13618.trc  
  2. HEAP DUMP heap name="sga heap"  desc=0x2000002c  
  3. HEAP DUMP heap name="sga heap(1,0)"  desc=0x2001b550  
  4. HEAP DUMP heap name="sga heap(1,1)"  desc=0x2001c188  
  5. HEAP DUMP heap name="sga heap(1,2)"  desc=0x2001cdc0  
  6. HEAP DUMP heap name="sga heap(1,3)"  desc=0x2001d9f8  
  7. HEAP DUMP heap name="sga heap(2,0)"  desc=0x20020640  
  8. HEAP DUMP heap name="sga heap(2,1)"  desc=0x20021278  
  9. HEAP DUMP heap name="sga heap(2,2)"  desc=0x20021eb0  
  10. HEAP DUMP heap name="sga heap(2,3)"  desc=0x20022ae8 

Oracle 10g中多缓冲池结构如图1-20所示。

  

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

 
 
  1. SQL> select addr,indx,kghluidx,kghludur,kghluops,kghlurcr  
  2. from x$kghlu;  
  3. ADDR        INDX    KGHLUIDX    KGHLUDUR      
  4. KGHLUOPS    KGHLURCR  
  5. --------    ----    ----------  ----------    
  6. ----------  ----------  
  7. B5F4C5B4    0           2           3         
  8. 12773       257  
  9. B5F4C1AC    1           2           2         
  10. 43675       1042  
  11. B5F4D9C8    2           2           1         
  12. 18831       1518  
  13. B5F4D5C0    3           2           0             
  14. 0           0  
  15. B5F4D1B8    4           1           3     
  16. 144697      327  
  17. B5F4E9E4    5           1       2       483428        
  18. 1462  
  19. B5F4E5DC    6           1           1       6558          
  20. 982  
  21. B5F4E1D4    7           1           0             
  22. 0           0  
  23. rows selected. 

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

虽然多缓冲池技术使Oracle可以管理更大的共享池,但是SubPool的划分可能也会导致各分区之间的协调问题,甚至可能因为内存分散而出现 ORA-04031错误。最常见的问题是某个子缓冲池(SubPool)可能出现过度使用,当新的进程仍然被分配到这个SubPool时,可能会导致内存 请求失败(而此时其他SubPool可能还有很多内存空间)。

因为子缓冲池存在的种种问题,从Oracle 10g开始,允许内存请求在不同SubPool之间进行切换(Switch),从而提高了请求成功的可能(但是显然切换不可能是无限制的,所以问题仍然可能存在)。

以下是来自客户系统的一个实际案例,在一个Oracle9i的系统中,经常出现ORA-04031的错误,客户系统的主要配置如下。

 
 
  1. SQL> select * from v$version where rownum <2;  
  2. BANNER  
  3. ----------------------------------------------------------------  
  4. Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production  
  5. SQL> show parameter cpu_count  
  6. NAME                                TYPE        VALUE  
  7. ------------------------------------    ----------- --  
  8. cpu_count                           integer     48  
  9. SQL> select * from v$sga;  
  10. NAME                                        VALUE  
  11. ------------------------------  ----------------  
  12. Fixed Size                              762240  
  13. Variable Size                           2600468480  
  14. Database Buffers                        18975031296  
  15. Redo Buffers                             6578176

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16856446/viewspace-628523/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16856446/viewspace-628523/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值