在ORA-4031 的10gR2版本中,引起"KGH: NO ACCESS"超出内存分配
适用于:
Oracle Server - Enterprise Edition - Version: 10.2.0.1 to 10.2.0.4 - Release: 10.2 to 10.2特征:
数据库运行几个小时之后, ORA-4031报错
查看ORA-4031栈文件显示:内存分配中一个叫”KGH: NO ACCESS"消耗了大量内存空间,以下是这个内存分配超过500M的例子.
Allocation Name Size
_________________________ __________
"free memory " 163766600
...
"KGH: NO ACCESS " 560713888
周期性的观察到"KGH: NO ACCESS"分配超过64M是正常的,这是内存在SGA组件之间进行过渡,当内存自动管理器改变SGA组件的时候就会发生这种情况,但是,当看到一个持续的高分配状态或者在这个分配状态下建立了一个稳定的状态就不正常了.当数据库需要进行大量数据改变时会发生这种异常.在超负荷或以次优SGA设置(比如没有使用SPFILE)启动的时候,内存就会改变.
以下的查询会使内存分配"KGH: NO ACCESS"相当大:
select * from v$sgastat where pool = 'shared pool' and (name in ('free memory', 'sql area', 'library cache', 'miscellaneous', 'row cache', 'KGH: NO ACCESS') );
以下查询是对于默认缓冲缓存区和共享池的扩张和收缩操作
ALTER SESSION SET nls_date_format = 'DD/MM/YYYY HH:MI:SS';
SET PAGESIZE 900
SET LINESIZE 255
COL COMPONENT FORMAT A25
COL INITIAL_SIZE FORMAT A10
COL FINAL_SIZE FORMAT A10
SPOOL ASMM_RESIZE.TXT
select START_TIME, component, oper_type, oper_mode, initial_size/1024/1024 "INITIAL", FINAL_SIZE/1024/1024 "FINAL", END_TIME
from v$sga_resize_ops
where component in ('DEFAULT buffer cache', 'shared pool') and status = 'COMPLETE'
order by start_time, component;
SPOOL END
原因:
对缓冲缓冲区和共享池频繁调整大小,导致超出"KGH: NO ACCESS"内存分配,消耗SGA内存.
在10gR2的不同版本中,许多漏洞已经记录了这个问题,稳定版本为:10.2.0.2
未发布的漏洞4507532:SGA_TARGET不能像预期的那样工作.
漏洞5045505 ASMM-频繁改变共享池和缓冲缓存的大小.
稳定版本:10.2.0.5
未发布的漏洞:7189722:大量会话等待,光标显示: PIN S WAIT ON X
稳定版本:10.2.0.5
未发布的漏洞:7189722: APPSST GSI 10G:频繁执行扩张和收缩SGA大小的操作.
如果在11.1.0.6 to 11.2.0.1中看到以上漏洞,请看注解: Note 1127833.1 ORA-04031 in 11g & 11gR2, Excess "KGH: NO ACCESS" Memory Allocation
解决方法:
主要有以下方法:
1. 禁用ASMM
2. 设置共享池和数据库缓冲缓存区的大小的最小值
3. 增加调整大小的操作的时间
4. 使用和当前版本相符的更新或者一次性补丁修补
当频繁调整ASMM的大小,导致SGA内存消耗出现"KGH: NO ACCESS"内存分配问题,使用以上方法可以解决此类问题,详见注解:
Note 451960.1 当ASMM运行的时候,如何防止共享池出现'KGH: NO ACCESS'
Note 742599.1 频繁调整SGA大小
禁用ASMM意味着内存在共享池中不再交换,但是它需要手动设置SGA的参数.
在ASMM激活的状态下设置共享池和缓冲缓存区的大小意味着:ASMM是可操作的,但是,在小于最小值的任何操作都是无效的,这样使得很少的内存通过"KGH: NO ACCESS"内存分配,不需要启动关闭数据库。
增加调整大小的操作时间是指增加默认30s的时间间隔。
最后,使用oracle 推荐的补丁或更新修补。
方法1:禁用ASMM和恢复SGA手动设置
1.确定SGA DB_CACHE_SIZE参数的合理值,想要更多的帮助,请查看注解Note 1008866.6 How to determine SGA Size (7.x, 8.0.x, 8i, 9i, 10g)
2.启用ASMM
SQL> alter system set SGA_TARGET=0 scope=spfile;
3.手动设置SGA池的大小,它的值为第一步确定的值。
例如:alter system set SHARED_POOL_SIZE=1G scope=spfile.
注意:不是所有的参数都需要设置,默认的设置都为0.
5. 关闭和启动数据库使ASMM禁用,手动设置生效。
方法2:启用ASMM,设置共享池和缓冲缓存区的最小值
1.在数据库繁忙时期运行以下查询语句:
SET PAGESIZE 100
COL COMPONENT FORMAT A25
COL FINAL_SIZE FORMAT A15
select component, AVG(FINAL_SIZE) "AVG FINAL", MEDIAN(FINAL_SIZE) "MEDIAN FINAL", MAX(FINAL_SIZE) "MAX FINAL"
from v$sga_resize_ops
group by component;
2.查看"DEFAULT buffer cache"行,将"AVG FINAL" 和"MEDIAN FINAL"中最大的值作为最小缓冲缓存区的大小,记为n
3.查看"shared pool"行,将"AVG FINAL" 和"MEDIAN FINAL"中最大的值作为最小共享池的大小,记为m
4.将最小缓冲缓存区和最小共享池的值加起来,然后和"AVG FINAL" 或 "MEDIAN FINAL"的大小做比较。
5.如果它的和比SGA_TARGET 或 SGA_MAX_SIZE大,那么这两个值也要增加,确定SGA_TARGET 或 SGA_MAX_SIZE的大小并设置:
SQL> ALTER SYSTEM SET SGA_TARGET=nnn SCOPE=BOTH;
6.设置参数DB_CACHE_SIZE,它和第二步的最小缓冲缓存区的大小是一样的
SQL> ALTER SYSTEM SET DB_CACHE_SIZE=n SCOPE=SPFILE;
7.设置参数SHARED_POOL_SIZE,它和第三步最小共享池大小是一样的
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE=m SCOPE=SPFILE;
8.重新启动数据库
9.你也可以不重启数据库改变内存设置,但是,你需要确定哪些动态设置是首先设置的,运行以下查询语句:
SQL> select component, current_size from v$sga_dynamic_components where component like '% pool' or component = 'DEFAULT buffer cache';
10.如果"shared pool" 和"DEFAULT buffer cache" 的值都小于2,3步确定的值,在设置DB_CACHE_SIZE 和SHARED_POOL_SIZE的值时使用SCOPE=BOTH。
方法3:增加调整大小的操作的时间
1.查看注解Note 742599.1,尤其是和参数"_memory_broker_stat_interval"相关的解决方案。
2.对于数据库,确定执行调整大小操作的时候需要的延迟时间,默认为30秒。
3.设置参数"_memory_broker_stat_interval",大小和第二步确认的大小相同。
4.关闭和启动数据库,相关参数设置生效。
方法4:使用补丁修补
10.2.0.1
如果你使用的是10.2.0.1版本,需要更新到10.2.0.3以上版本
10.2.0.2
如果你使用的是10.2.0.2,在这个版本中没有记录漏洞,因此它建议你更新。
10.2.0.3
1.下载和检查补丁6528336(2009.4)的readme和必需条件。适用平台:Linux x86, IBM AIX 64-bit, HP-UX Itanium
2.如果你的平台不存在该补丁,登录服务请求,请求漏洞6528336的backport
10.2.0.4
1.下载和检查补丁7189722(2009.4)的readme和必需条件。适用平台:Linux x86, Linux x86-64, IBM AIX 64-bit, HP-UX Itanium, Sun Solaris SPARC 64-bit.
2.如果你的平台不存在该补丁,登录服务请求,请求漏洞7189722的backport,或者oracle推荐你更新到10.2.0.5版本(你的平台适用该版本)