什么情况可能导致共享池出现 ORA4031

2024年 5月 22日 75.6k 0

原文: DBA的思想天空- p67

第四个问题是什么情况可能导致共享池出现 ORA-4031呢?老白最初接触共享池的时候,总觉得共享池既然是可以通过 LRU算法换出的,那么应该不会出现不足的情况啊。随着对共享池内存分配和管理算法的研究深入,才发现释放共享池内存是有条件的,当前被锁住的内存是不能释放的。如果当前正好有个会话在执行,那么其游标相关的所有内存对象必须是锁住的,不能随便释放,否则这个 SQL的执行就会出现问题。正因为这样,在系统并发量很大的时候,由于很多共享池的内存是被锁住无法释放的,共享池的空闲空间就被分割为无数个很小的碎片,可能无法满足一些较大的分配,出现 ORA-4031也就不可避免了。

 

在这种情况下,我们可以认为共享池不足导致了问题,如果共享池的空间再大一点,出现内存不足的可能性也就会下降。除了共享池不足,还有什么情况可能导致 ORA-4031呢?前面所说的那种情况,是由于系统并发量很大,大量的共享池内存被锁住而无法释放。一旦系统负载下降,共享池就会逐渐恢复正常。另外一种情况就是,共享池中的一些 LIST对象(比如LOCK、RESOURCE等)初始化分配了一部分空间,如果这部分列表用完了,可以动态扩展。由于这些扩展是永久性的,所以,它们就像共享池中钉下的一颗颗钉子,是无法拔掉的。如果这类扩展十分频繁,那么时间长了,共享池就会被这些“钉子”分割为很多碎片。这种碎片化是永久性的,随着实例启动时间的推移,会越来越严重,而且无法自动或者手工修复。积累到一定程度,这个系统就会出现严重的碎片化问题,从而出现ORA-4031,甚至导致宕机。

 

对于这种系统,一般来说可以通过三个渠道来优化:

第一个渠道是加大共享池,使之碎片化的时间推迟,但是这只是延迟碎片化,不能避免碎片化;

第二个渠道是定期重启实例,通过重启实例,恢复共享池的内存空间,确保系统正常运行,不出现宕机现象,不过要做到这一点,对于大多数7x24的系统来说十分困难;

第三个是扩大经常动态扩展的列表对象的初始大小,减少其动态扩展的次数,最好能够让它们不再动态扩展,这个做法会浪费一定的共享池空间,但却是解决这个问题最好的方法。

 

似乎问题都解决了,好像共享池也没那么复杂嘛,只要给共享池足够的空间,它就会很好地工作了。实际上并没有这么简单。还是接着刚才 ORA-4031的问题往下讨论吧。如果分配了很大的共享池,经过一段时间的运行后,它变得很零碎了,这时我们要分配一个较大的连续空间。共享池中没有这么大的 Chunk可用,那么就会开始释放空间,而释放空间的时候,需要持有共享池的闩锁,

 

因此在释放共享池空间时,为了确保共享池闩锁被持有的时间不会太长,Oracle内部对释放 Chunk的数量做了限制,一旦超过这个限制,这个小型的FLUSH操作就会停止。这种情况下,虽然共享池中的空闲空间是足够分配的,但也会出现ORA-4031错误。另外由于大量碎片释放时,共享池闩锁是被持有的,并发的其他会话也会受到一定的影响。因此在共享池碎片化特别严重的时候,出现共享池性能故障和 ORA-4031的可能性就会大大增加。所以我们在理解共享池的工作原理并将其应用在实际工作中时,还是不能过于简单化。

 

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论