共计 3306 个字符,预计需要花费 9 分钟才能阅读完成。
问题描述
某用户 Oracle 数据库数据库突然宕机,查看日志发现宕机前大量出现如下错误:
Errors in file /u01/oracle/admin/orcl/bdump/orcl2_smon_14347.trc:
ORA-00604: Message 604 not found; No message file for product=RDBMS, facility=ORA; arguments: [2]
ORA-04031: Message 4031 not found; No message file for product=RDBMS, facility=ORA; arguments: [32] [shared pool] [select /*+ rule */ bucket_cn...] [sql area] [tmp]
Thu Nov 12 15:43:54 2015
Errors in file /u01/oracle/admin/orcl/bdump/orcl2_smon_14347.trc:
ORA-00604: Message 604 not found; No message file for product=RDBMS, facility=ORA; arguments: [2]
ORA-04031: Message 4031 not found; No message file for product=RDBMS, facility=ORA; arguments: [32] [shared pool] [select /*+ rule */ bucket_cn...] [sql area] [tmp]
Thu Nov 12 15:43:55 2015
WARNING: inbound connection timed out (ORA-3136)
Thu Nov 12 15:43:56 2015
WARNING: inbound connection timed out (ORA-3136)
Thu Nov 12 15:43:58 2015
WARNING: inbound connection timed out (ORA-3136)
Thu Nov 12 15:43:59 2015
Errors in file /u01/oracle/admin/orcl/bdump/orcl2_smon_14347.trc:
ORA-00604: Message 604 not found; No message file for product=RDBMS, facility=ORA; arguments: [2]
ORA-04031: Message 4031 not found; No message file for product=RDBMS, facility=ORA; arguments: [32] [shared pool] [select /*+ rule */ bucket_cn...] [sql area] [tmp]
Thu Nov 12 15:44:00 2015
Errors in file /u01/oracle/admin/orcl/bdump/orcl2_smon_14347.trc:
ORA-00604: Message 604 not found; No message file for product=RDBMS, facility=ORA; arguments: [2]
ORA-04031: Message 4031 not found; No message file for product=RDBMS, facility=ORA; arguments: [32] [shared pool] [select /*+ rule */ bucket_cn...] [sql area] [tmp]
Thu Nov 12 15:44:00 2015
WARNING: inbound connection timed out (ORA-3136)
Thu Nov 12 15:44:01 2015
Errors in file /u01/oracle/admin/orcl/bdump/orcl2_smon_14347.trc:
ORA-00604: Message 604 not found; No message file for product=RDBMS, facility=ORA; arguments: [2]
ORA-04031: Message 4031 not found; No message file for product=RDBMS, facility=ORA; arguments: [32] [shared pool] [select /*+ rule */ bucket_cn...] [sql area] [tmp]
Thu Nov 12 15:44:02 2015
WARNING: inbound connection timed out (ORA-3136)
Thu Nov 12 15:44:02 2015
Errors in file /u01/oracle/admin/orcl/bdump/orcl2_smon_14347.trc:
这里 ORA-04031 很清楚地表示出来,是在向 shared pool 申请内存时失败。
shared pool 内存申请(分配)失败,通常有如下的几种可能:
- shared pool 过小,比如在 SGA Manual Management 方式下,shared pool 设置过小。比如一套数千连接的大系统,shared pool 只设置了几百 M。这种情况下,要解决问题很解单,增加 shared pool 的大小即可。
- 应用没有使用绑定变量,硬解析非常多,导致 shared pool 内存碎片严重,分配大块内存时不能获得连续的内存空间。硬解析多的一个变种是虽然使用了绑定变量,但是由于某种原因,Cursor 不能共享,导致 Child Cursor 非常多。实际上,如果 shared pool 较大(比如数 GB 大小),这种问题还是很少出现的,并且出现也通常出现在申请大块内存时。这种情况如果使用 alter system flush shared_pool 可以暂时缓解问题。但是这条命令又通常不适用于 shared pool 较大而且比较繁忙的系统。使用绑定变量
- Cache 的 cursor 很多,同时 cursor_space_for_time 这一参数设置为 TRUE,可能会使 shared pool 碎片化严重,导致不能分配到大块的连续内存。
- Oracle 的 BUG 导致内存泄露,比如在一些版本中查询 v$segment_statistics 这样的视图导致内存泄露,使 shared pool 内存耗光。同样的情形还有类似于“obj stat memory”,”gcs resources”,”ges resources”等。通常这类内存为 perm 类型(permanet),这类内存通常是在分配时就确定了固定的用途,不能用于其他用途,因此极容易产生碎片。
- Oracle 从 9i 开始,根据 shared pool 的大小将 shared pool 分为多个子池(subpool),每个子池有独立的 free list,同时在分配时单独管理(有其独立 的 shared pool latch)。Oracle 的 BUG 或者说是内存分配策略缺陷导致某一类 shared pool 的内存分配只在一个子池 (subpool) 中,即多个子池的使用极不均衡,导致向那个使用得最多的子池申请内存时失败。报错信息中的”sga heap(3,0)”即指明是在第 3 个子池申请内存时失败。本文案例中的 ORA-04031 错误其产生的原因可以归结为 Oracle 对 shared pool 的分配 / 使用策略问题。
- 操作系统内存不足,这只会出现在 shared pool 的使用还没有达到最大值时才会出现,并且在操作系统都有 swap 的情况下,只有部分操作系统才可能有这种情况,比如在 HP-UX 下,reserved 内存过多导致 swap 满。
- 其他原因,多数是因为 BUG。
解决方法
根据问题分析,可以尝试 2 种方式解决:1. 分配更大的共享池(根据 awr 报告建议来设置);2. 定期刷新共享池,避免过多的碎片(可能存在解析风险)
更多 Oracle 相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-11/137675.htm
正文完
星哥玩云-微信公众号