查看: 13811|回复: 50

【大话IT】ORA-4031报错:如何正确释放内存

[复制链接]
认证徽章
论坛徽章:
127
茶鸡蛋
日期:2012-01-16 14:24:41鲜花蛋
日期:2012-06-06 14:48:18双黄蛋
日期:2013-01-07 21:07:482013年新春福章
日期:2013-02-25 14:51:24优秀写手
日期:2013-12-18 09:29:082014年新春福章
日期:2014-02-18 16:44:08马上有对象
日期:2014-02-18 16:44:08马上加薪
日期:2014-03-18 09:57:11马上有车
日期:2014-03-20 16:13:24马上有房
日期:2014-03-20 16:14:11
发表于 2014-10-27 10:32 | 显示全部楼层 |阅读模式

想想看,遇到ORA-4031错误时,你的心里会不会发怵?ORA-4031很容易导致数据库出现异常崩溃,当Oracle的核心进程无法获得共享池内存时,它们会把数据库异常宕掉。当然,ORA-4031就像黄灯一样,它在提醒你需要马上采取紧急策略了。不是说它一出现,数据库马上就会宕机。


话题讨论:

1.ORA-4031是Oracle中最令人厌恶的报错,它的出现有哪几种原因?


2.一旦出现4031错误,也就是说共享池内存不足的情况下,我们该如何释放内存呢?你有木有遇到过相应的情形呢?请回忆下当时是如何解决的?


3.有一句俗语叫丢车保帅,执行计划是SQL核心关键所在,是否意味着在释放内存时,不应该覆盖执行计划这部分?当执行计划部分占用内存比较多时,如何优化呢?


4.消耗共享池内存的主要有两种对象,一种是SQL,而是存储过程、函数、包等这类可执行对象,当遇到4031错误时,您觉得需要优先释放哪种对象?


活动时间:2014年10月27日-11月15日

活动奖励:根据大家的回复情况我们评选获奖会员

苦劳奖:回复次数最多的2名 赠送技术图书1本+社区徽章1枚

功劳奖:回复质量最高的网友1名 赠送技术图书1本





发表于 2014-10-28 13:25 | 显示全部楼层
这就需要从shared pool 的内存结构来分析了, 首先shared pool 有许多的内存块组成,这些内存块通常叫做chunk

chunk是 shared pool这是内存分配的最小单位,其中的内存都是连续的。

chunk 分为四个类型,可以从 X$ksmsp中的 ksmchcls列看到 ,X$ksmsp视图中的每条记录都表示在当前shared pool 中的一个chunk

1) free 这种类型的chunk不包含有有效的对象,可以被分配。

2)  recr 表示recreatable,这种类型的chunk 里面包含的对象可以在需要的时候被临时移走,并且在需要的时重新创建。

    比如对于很多的共享SQL的chunk就是recreatable的。

3) freeabl 这种类型的chunk 包含的对象是曾经被session 使用过的。并且随后会被完全或者部分释放。这种chunk

    不能被临时从内存中移走,因为他们是在处理过程中产生的,如果移走就不能被重建。

4) perm 意味着永久性,这种类型的chunk包含永久的对象,大型的permanent类型的chunk也可能包含有用的空间,

    这部分可用空间可以在需要的时候释放。

在shared pool 中可用的chunk(也就是free类型的)会被连接起来成为 free list 或者叫bucket(一个free list就是一个bucket)

每个backet中的chunk的大小是不同的。

当某个进程需要shared pool 里面的一个chunk,该进程首先倒伏后所需空间大小的backet上去扫描,以找到最合适的chunk,扫描持续到backet

的最末端,值到找到尺寸符合的chunk为止,如果找到的chunk尺寸必须要的要大,则这个被找到的chunk就会被拆分一个用来存储数据

另一个成为free类型的chunk 并成为当前的bucket。

当某个bucket不包含有任何尺寸的chunk,那么就从下一个非空的backet上获得一个最小的chunk,如果在剩下的所有的backet中都找不到可用的chunk

则需要扫描已经使用的recreatable类型的chunk。从该链表上释放出部分chunk,因为只有recreatable类型的chunk才是可以被临时一处内存的。

但某个chunk正在被使用时该chunk是不能被移除内存的。比如某个SQL语句正在执行,那么该语句所使用的chunk就不能被移除内存。该SQL所引用的表,索引

等对象占用的chunk也不能够被移除内存,当shared pool中无法找到满足大小的所需内存时就会出现ORA-4031的错误。

当出现ORA-4031的错误的时候,我们查询V$SGSTAT中的可用shared pool空间时,可能发现可用的内存足够大了,为什么还是出现ORA-4031错误呢?

事实上,在oracle发出错误之前已经释放出大量的recreatable类型的chunk了因此会产生不少的可用内存。但是这些可用的chunk中没有一个是连续的从而

才发出ORA-4031的错误。

使用道具 举报

回复
求职 : 数据库管理员
招聘 : Java研发
认证徽章
论坛徽章:
6350
ITPUB9周年纪念徽章
日期:2014-05-02 10:36:402011新春纪念徽章
日期:2014-12-29 12:11:142010广州亚运会纪念徽章:卡巴迪
日期:2014-08-06 08:44:252012新春纪念徽章
日期:2014-12-29 12:11:142013年新春福章
日期:2014-12-29 12:11:14马上有车
日期:2014-12-29 12:11:14马上有房
日期:2014-12-29 12:11:14马上有钱
日期:2014-12-29 12:11:14马上有对象
日期:2014-12-29 12:11:14马上加薪
日期:2014-12-29 12:11:14
发表于 2014-10-27 11:15 | 显示全部楼层
占楼:
遇到过的是SGA 配置过低;SQL 未绑定变量导致这个问题~

使用道具 举报

回复
认证徽章
论坛徽章:
17
生肖徽章2007版:猴
日期:2015-07-24 10:50:33紫水晶
日期:2015-09-14 19:29:07萤石
日期:2015-09-14 19:24:48萤石
日期:2015-09-13 14:30:02萤石
日期:2015-09-11 23:05:02红宝石
日期:2015-09-11 23:04:43萤石
日期:2015-09-11 23:04:27生肖徽章2007版:兔
日期:2015-07-31 16:43:10生肖徽章2007版:龙
日期:2015-07-24 10:51:00生肖徽章2007版:龙
日期:2015-07-24 10:50:51
发表于 2014-10-27 11:35 | 显示全部楼层
占楼11111

使用道具 举报

回复
认证徽章
论坛徽章:
64
状元
日期:2015-07-20 15:43:53榜眼
日期:2015-07-16 12:57:31探花
日期:2015-07-06 10:48:48进士
日期:2015-06-25 16:41:54举人
日期:2015-06-18 09:00:04秀才
日期:2015-08-06 13:55:21秀才
日期:2015-06-30 10:57:59秀才
日期:2015-07-17 10:06:26秀才
日期:2015-07-20 08:54:46秀才
日期:2015-07-20 09:00:26
发表于 2014-10-27 11:40 | 显示全部楼层
苦劳奖:回复次数最多的2名 赠送技术图书1本+社区徽章1枚

一直回「學習」有送不?

使用道具 举报

回复
认证徽章
论坛徽章:
244
2015年新春福章
日期:2015-05-28 10:58:322015年新春福章
日期:2015-03-19 09:32:472015年新春福章
日期:2015-03-06 11:58:182015年新春福章
日期:2015-05-21 11:46:522015年新春福章
日期:2015-05-22 13:32:002015年新春福章
日期:2015-06-25 14:26:362015年新春福章
日期:2015-07-01 17:15:212015年新春福章
日期:2015-07-01 17:15:212015年新春福章
日期:2015-07-01 17:12:082015年新春福章
日期:2015-05-18 13:50:34
发表于 2014-10-27 11:44 | 显示全部楼层
错误的原因,一般是大量的Hard Parse 导致了shared pool中的free list中产生大量的内存小碎片,当一个需要很大内存来进行hard parse的sql语句到来时,无法从free list中找到内存,即使进行内存的释放,还是不能找到符合的内存块。从而报ORA-4031错误。

ORA-4031错误的解决方法:
1)alter system flush shared_pool;将shared pool中的所有内存清空。该方法治标不治本。
2)共享SQL语句:规范SQL语句的书写;使用绑定变量;找到没有使用绑定变量的SQL:
   如果在结果中发现一系列仅仅字面值不同的SQL,则可以修改cursor_sharing参数:
   alter system set cursor_sharing = 'force'; 来强制使用绑定变量。
3)使用shared pool中的保留区:
   select request_misses from v$shared_pool_reserved;
   如果结果大于0,则可以调大shared_pool_reserved的大小;
4)使用dbms_shared_pool.keep('对象名')将使用内存很大的对象keep在内存中
5)增加shared_pool_size的大小:

使用道具 举报

回复
认证徽章
论坛徽章:
244
2015年新春福章
日期:2015-05-28 10:58:322015年新春福章
日期:2015-03-19 09:32:472015年新春福章
日期:2015-03-06 11:58:182015年新春福章
日期:2015-05-21 11:46:522015年新春福章
日期:2015-05-22 13:32:002015年新春福章
日期:2015-06-25 14:26:362015年新春福章
日期:2015-07-01 17:15:212015年新春福章
日期:2015-07-01 17:15:212015年新春福章
日期:2015-07-01 17:12:082015年新春福章
日期:2015-05-18 13:50:34
发表于 2014-10-27 11:44 | 显示全部楼层

使用道具 举报

回复
认证徽章
论坛徽章:
12
青年奥林匹克运动会-铁人三项
日期:2014-09-22 09:51:212015年新春福章
日期:2015-03-06 11:59:472015年新春福章
日期:2015-03-04 14:55:13凯迪拉克
日期:2014-11-20 09:13:05itpub13周年纪念徽章
日期:2014-11-06 15:29:09马上加薪
日期:2014-10-28 09:44:43itpub13周年纪念徽章
日期:2014-10-09 14:40:48马上有房
日期:2014-10-09 10:14:27马上有车
日期:2014-10-09 10:14:27itpub13周年纪念徽章
日期:2014-10-08 15:15:25
发表于 2014-10-27 11:53 | 显示全部楼层
xkf01 发表于 2014-10-27 11:44
错误的原因,一般是大量的Hard Parse 导致了shared pool中的free list中产生大量的内存小碎片,当一个需要 ...

生产库flush shared pool不好吧

使用道具 举报

回复
论坛徽章:
92
2011新春纪念徽章
日期:2011-01-25 15:42:33咸鸭蛋
日期:2012-03-19 10:46:00版主1段
日期:2012-05-15 15:24:11奥运会纪念徽章:排球
日期:2012-08-29 07:02:50奥运会纪念徽章:跳水
日期:2012-09-26 06:44:27ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32奥运会纪念徽章:击剑
日期:2012-10-12 07:20:332013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-02-13 15:13:20
发表于 2014-10-27 12:13 | 显示全部楼层
如果是shared pool 4031,加大shared pool size
如果是large pool 4031,加大large pool size.


如果要避免4031,监控v$sgastat各个sub pool的增长,并且监控sub pool 0的大小

使用道具 举报

回复
论坛徽章:
490
2014年世界杯参赛球队:喀麦隆
日期:2015-08-17 16:10:052014年世界杯参赛球队:墨西哥
日期:2015-08-17 16:10:052014年世界杯参赛球队: 波黑
日期:2015-08-17 16:09:252014年世界杯参赛球队: 阿尔及利亚
日期:2015-08-17 16:09:082014年世界杯参赛球队: 澳大利亚
日期:2015-08-17 16:09:522014年世界杯参赛球队: 智利
日期:2015-08-17 16:09:522014年世界杯参赛球队:巴西
日期:2015-08-17 16:10:052014年世界杯参赛球队: 智利
日期:2015-08-17 16:09:522014年世界杯参赛球队: 意大利
日期:2015-08-17 16:09:392014年世界杯参赛球队:巴西
日期:2015-08-17 16:10:05
发表于 2014-10-27 12:16 | 显示全部楼层
扩!!!!!!!

使用道具 举报

回复
认证徽章
论坛徽章:
86
秀才
日期:2015-09-21 09:46:16目光如炬
日期:2014-07-28 06:00:03马上有钱
日期:2014-06-16 15:55:42马上有房
日期:2014-06-16 15:55:422014年世界杯参赛球队: 伊朗
日期:2014-06-13 11:29:242014年世界杯参赛球队:巴西
日期:2014-06-06 14:36:14马上有钱
日期:2014-04-04 13:51:21马上加薪
日期:2014-04-04 13:35:40马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:02
发表于 2014-10-27 13:07 | 显示全部楼层
占楼,更新

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表