我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
本案例来自一位同事的分享,主要现象是在 Oracle 11.2.0.4 的 RAC 环境中,节点2频繁出现 ORA-04031 错误。以下是详细的分析过程和处理建议。
一、什么是 ORA-04031 错误?
ORA-04031 错误的全称是 “unable to allocate X bytes of shared memory”,即“无法分配 X 字节的共享内存”。它通常发生在 Oracle 数据库的 Shared Pool 或其他 SGA 区域内存不足时。常见的报错信息如下:
Errors in file /u01/app/oracle/diag/rdbms/htz/htz2/trace/htz2_m000_319672.trc (incident=226253):
ORA-04031: unable to allocate 4160 bytes of shared memory ("shared pool","unknown object","sga heap(6,0)","modification ")
1.1 ORA-04031 的常见原因
- Shared Pool 设置过小,无法满足 SQL 解析、PL/SQL 代码、数据字典缓存等需求。
- 内存碎片化,虽然总内存充足,但没有足够大的连续内存块可用。
- 某些组件(如游标、包、过程等)频繁分配和释放内存,导致碎片。
- 特定参数设置(如启用 AMM/ASMM、duration 机制)导致内存分配异常。
1.2 报错中的关键字段解释
"shared pool"
:表示分配内存失败的区域是 Shared Pool。"unknown object"
:分配内存时的对象类型。"sga heap(6,0)"
:具体的 subpool 和 duration,本文重点关注 duration 0。"modification "
:分配内存的原因。
二、分析过程
通过报错信息中的 sga heap(6,0)
可以看出,所有报错都来自 subpool 6 的 duration 0。
通常分析 ORA-04031 问题时,可以查看对应的 trace 文件,确认是否生成了 heapdump。如果没有,可以在业务低峰期手动采集 heap dump。但要注意,dump heap 操作会长时间持有 shared pool latch,可能导致数据库 hang 住。也可以通过查询 X$KSMSP
视图分析内存分布,但对于较大的 shared pool,这种查询也可能带来性能风险。
2.1 采集 heap dump 的方法
oradebug setmypid;
oradebug unlimit;
oradebug dump heapdump 536870914;
oradebug tracefile_name;
oradebug close_trace;
Level 参数说明
536870914
这个参数的含义如下:
- 0x2 = SGA summary
- 0x20000000 = 所有 heap 的 top sub heap 信息(LARGEST SUB HEAPS)
常用 level 说明如下:
1 PGA summary
2 SGA summary
4 UGA summary
8 Callheap (Current)
16 Callheap (User)
32 Large pool
64 Streams pool
128 Java pool
1025 PGA with contents
2050 SGA with contents
4100 UGA with contents
8200 Callheap with contents (Current)
16400 Callheap with contents (User)
32800 Large pool with contents
65600 Streams pool with contents
131200 Java pool with contents
采集到 heapdump 后,可以用 tp 大神的 heapdump_analyzer 脚本或 Oracle 官方的 heap.awk 工具进行分析。
2.2 heapdump 结果分析
示例分析结果如下:
--> HEAP DUMP heap name="sga heap(6,0)" desc=0x6008bf00
Type Count Sum Average
~~~~ ~~~~~ ~~~ ~~~~~~~
perm 6 81833176 13638862.67
free 5 8336 1667.20
R-stopper 6 288 48.00
R-free 3 40267144 13422381.33
可以看到,subpool 6 duration 0 几乎被 perm 类型的 chunk 占满,free 的 32% 是保留池的 chunk。
详细分配如下:
Total_size #Chunks Chunk_size, From_heap, Chunk_type, Alloc_reason
29618736 1 29618736 , sga heap(6,0), perm, perm
50782208 1 50782208 , sga heap(6,0), perm, perm
...
几乎所有 perm 类型的内存都分配到了每个 subpool 的 duration 0。
三、为什么 duration 0 会频繁报 ORA-04031?
当启用 AMM/ASMM 并开启 duration 机制时,几乎所有 perm 类型的 chunk 都会分配到 duration 0。perm chunk 一旦分配给某个 shared pool 组件的 heap 后不会释放,也不能被其他组件使用,容易导致 duration 0 的 ORA-04031。
在 RAC 环境下,db cache 较大时会分配大量 perm chunk 给 RAC 特有的 shared pool 组件(如 gcs shadows、gcs resources、ges resources 等)。如果 shared pool 已经设置为合理大小,建议关闭 duration 机制。
四、处理建议
如果确认 shared pool 已经足够大,但仍频繁出现 ORA-04031,可以尝试关闭 duration 机制:
alter system set "_enable_shared_pool_durations"=false scope=spfile;
注意:该参数为隐含参数,修改前请充分评估风险,并在测试环境验证。
五、总结与建议
- ORA-04031 是 Oracle 数据库中常见的内存分配错误,通常与 shared pool 设置、内存碎片化、参数配置有关。
- 通过 heapdump 可以定位具体的内存分配情况,分析 perm chunk 的分布。
- 在 RAC 环境下,合理设置 shared pool,并根据实际情况考虑关闭 duration 机制,有助于缓解该类问题。
- 建议定期监控 shared pool 使用情况,及时调整参数,避免生产环境出现严重内存分配故障。
——————作者介绍———————–
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)
故障处理:ORA-04031真实案例分享:等您坐沙发呢!