现在的位置: 首页 > 综合 > 正文

深入内存组件shared pool–之ORA-04031错误

2013年10月11日 ⁄ 综合 ⁄ 共 1758字 ⁄ 字号 评论关闭

 04031的错误是和我们的shared pool相关,当我们的shared pool设置的不够大的时候,会因为 

没有足够的内存空间而导致改错误的发生,这个时候我们加大shared pool的空间就可以解决问题了 
不过有的朋友很细心, 在错误的时候,查询一下当前shared_pool的状况,发现还有free的空间, 
怎么也会提示这样的错叻。 

但是有时我们发现现在的shared pool的free size明明是够用的,但是还是提示有这个错。 
是Oracle的统计有问题,还是bug呢。 

我们首先来看看04031这个错误 

04031, 00000, 
"unable to allocate %s bytes of shared memory (/"%s/",/"%s/",/"%s/",/"%s/")" 
// *Cause: More shared memory is needed than was allocated in the shared 
// pool. 
// *Action: If the shared pool is out of memory, either use the 
// dbms_shared_pool package to pin large packages, 
// reduce your use of shared memory, or increase the amount of 
// available shared memory by increasing the value of the 
// INIT.ORA parameters "shared_pool_reserved_size" and 
// "shared_pool_size". 
// If the large pool is out of memory, increase the INIT.ORA 
// parameter "large_pool_size". 

在共享池中试图分配大片的连续内存失败的时候,Oracle首先清除池中当前没使用的所有对象,使空闲内存块合并。如果仍然没有足够大单个的大块内存满足请求,就会产生ORA-04031错误。 

究竟为何叻? 

主要是shared pool的碎片的问题,我们知道在shared pool里内存是以chunk为单位进行分配的,当我们使用过一个chunk,放到sharedpool的cache里,当有其他的请求需要shared pool申请空间的哦时候,shared pool会在freelist上进行查找,如果可以查找好需要size大chunk,那么shared pool就直接申请给他,如果没有的话,shared pool会清除一些已经没有使用过的chunk,然后合并chunk,chunk是相邻的,当我们在合并的时候,由于以前的chunk分配的小,所以形成比较多的fragment,所以有时候确实导致,明明已经清理了很多的chunk出来了,但是还是合并不成大的空间,就是因为这些碎片分的太细了,而且有没有连续的chunk连起来可以满足新申请的要求的,这样就是导致了明明有free size却组织不出空间来,从而导致04031的问题。 在9i, Oracle对这块进行了改进,在freelist的bucket里,每个bucket挂载的是不同size的chunk的列表,这样在请求一个新的cache的时候,通过这个size来进行匹配,详细的图可以在我的"基础知识和体系架构"的ppt里找到, 这样在每次分配的时候,Oracle各合理和合适的按照请求的size来找chunk,优化chunk的碎片化的粒度。从而能够比较好的降低上04031的发生几率,在9i以前,没有这样的机制,每个chunk的size在freelist都是一样的,这样产生碎片的几率相当的大。不过虽然Oracle在9i里加上了上面的处理机制,也不能完全避免该错误的发生,如果我们使用的不好,还是会发生这样的问题。 

当发现这样的问题,解决方法 

1. 确定我们的shared_pool_size的配置是否分配的恰当。 同时也主要要查看v$shared_pool_reserved视图,是不是我们我们这里的一些大sql的解析的空间也出现问题了; 

2. 使用参数绑定,避免过度的解析

抱歉!评论已关闭.