我们的文章会在微信公众号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)
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |