Oracle RAC节点内存“泄漏”多为PGA/SGA配置与负载不匹配所致,须先查v$parameter确认AMM(memory_target>0)或ASMM(sga_target与pga_aggregate_target均>0)模式,再针对性分析V$PGASTAT/V$SGASTAT。
查V$PGASTAT和V$SGASTAT之前先确认AMM/ASMM状态
oracle rac节点内存“泄漏”八成不是真泄漏,而是pga或sga配置与实际负载不匹配导致的内存持续上涨。第一步必须确认当前用的是哪种内存管理模式:memory_target、sga_target+pga_aggregate_target,还是全手工(shared_pool_size等显式设值)。执行:
select name, value from v$parameter where name in ('memory_target', 'memory_max_target', 'sga_target', 'pga_aggregate_target');若memory_target > 0,则amm启用,_sga和_pga是只读的,改了会报ora-00843;若sga_target > 0且pga_aggregate_target > 0,则是asmm,此时_pga_aggregate_limit不生效;只有amm下,_pga_aggregate_limit才可能起硬限制作用。
PGA爆涨但V$SESSION里没大进程?重点看后台进程和INMEMORY解压缓冲区
RAC节点PGA占用高却找不到对应会话,常见于三类被忽略的消耗源:
-
V$PROCESS里PROGRAM为ora_d000_*(调度进程)、ora_cjq0_*(作业队列)或ora_mmon_*(自动内存监控)的进程,它们在AWR快照收集、SQL Tuning Advisor运行时会临时吃掉几百MB PGA - 启用了
INMEMORY时,每个压缩单元(CU)解压到内存做计算时,缓冲区计入PGA——但V$SQL_WORKAREA不统计这部分,需查V$INMEMORY_AREA中bytes_used与bytes_not_populated差值 - RAC Cache Fusion本身不走PGA,但GC等待堆栈(如
gc current block 2-way争用严重时)会触发大量后台PL/SQL解析,而DBMS_SQL.PARSE操作的内存分配走PGA,且不体现在V$SQL_WORKAREA_ACTIVE
验证方法:运行SELECT program, pga_used_mem/1024/1024 MB FROM v$process ORDER BY 2 DESC,重点关注非oracle@开头但pga_used_mem超200MB的行。
_PGA_AGGREGATE_LIMIT设了但ORA-04036不触发?检查是否满足生效前提
很多DBA写了ALTER SYSTEM SET "_pga_aggregate_limit"=6G SCOPE=SPFILE SID='rac2'就以为万事大吉,结果OOM照样发生。这个参数只在两个条件同时满足时才真正参与判断:
- 数据库必须启用AMM(即
memory_target > 0),且未设置pga_aggregate_target(设了就会退回到ASMM逻辑,忽略该隐含参数) - RAC每个节点必须单独配置,不能靠集群同步——
SID='rac2'必须精确匹配该节点实例名,否则写进SPFILE但不生效
验证是否生效:查V$PGASTAT,看aggregate PGA auto target和global memory bound两列数值是否接近你设的6G。如果仍是0或远低于设定值,说明参数根本没加载进来。再查V$SPPARAMETER确认sid列是否匹配当前节点。
SGA明明只配了20G,top里RSS却飙到48G?别漏掉共享内存段和hugepage碎片
RAC节点ipcs -m显示共享内存段总和远超sga_max_size,常见于以下情况:
- Linux启用了
use_large_pages=only但memlock没调够,Oracle fallback到大量小页分配,造成shmid数量爆炸(每个小页段独立申请),ipcs -m里出现成百上千个几MB的小段 - 启用了
INMEMORY后,inmemory_area大小不计入sga_max_size,但实际占用物理内存——查V$INMEMORY_AREA确认是否额外占了5~10G - RAC中某节点曾执行过
ALTER SYSTEM FLUSH SHARED_POOL,但Shared Pool未完全释放(尤其有大量Adaptive Cursor Sharing子游标时),V$SGASTAT里free memory可能为0,而ipcs仍持有已分配但未归还的段
关键动作:用cat /proc/<pid>/maps | grep "shmid" | wc -l看Oracle进程映射了多少共享内存段;若超过500,基本可判定是hugepage配置失败导致的小页泛滥。


















