`
algorithm
  • 浏览: 8620 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

ora-04031错误解决方法及详细分析

阅读更多
看到系统报这个错,重启weblogic不行,重启Oracle后解决。

java.sql.SQLException: ORA-04031: unable to allocate 27996 bytes of shared memory ("shared pool","unknown object","sga heap(1,0)","session parame")

java.sql.SQLException: ORA-04031: 无法分配 27996 字节的共享内存 ("shared pool","unknown object","sga heap(1,0)","session parame")

转载一篇解决此问题的文章


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


1.共享池相关的实例参数

在继续之前,有必要理解下面的实例参数:

SHARED_POOL_SIZE

这个参数指定了共享池的大小,单位是字节。可以接受数字值或者数字后面跟上后缀"K" 或 "M" 。"K"代表千字节, "M"代表兆字节。

SHARED_POOL_RESERVED_SIZE

指定了为共享池内存保留的用于大的连续请求的共享池空间。当共享池碎片强制使 Oracle 查找并释放大块未使用的池来满足当前的请求的时候,这个参数和SHARED_POOL_RESERVED_MIN_ALLOC 参数一起可以用来避免性能下降。

这个参数理想的值应该大到足以满足任何对保留列表中内存的请求扫描而无需从共享池中刷新对象。既然操作系统内存可以限制共享池的大小,一般来说,你应该设定这个参数为 SHARED_POOL_SIZE 参数的 10% 大小。
SHARED_POOL_RESERVED_MIN_ALLOC 这个参数的值控制保留内存的分配。如果一个足够尺寸的大块内存在共享池空闲列表中没能找到,内存就从保留列表中分配一块比这个值大的空间。默认的值对于大多数系统来说都足够了。如果你加大这个值,那么Oracle 服务器将允许从这个保留列表中更少的分配并且将从共享池列表中请求更多的内存。这个参数在Oracle 8i 和更高的版本中是隐藏的。提交如下的语句查找这个参数值:

SELECT nam.ksppinm NAME, val.ksppstvl VALUE FROM x$ksppi nam, x$ksppsv val WHERE nam.indx = val.indx AND nam.ksppinm LIKE '%shared%'ORDER BY 1;10g 注释:Oracle 10g 的一个新特性叫做 "自动内存管理" 允许DBA保留一个共享内存池来分shared pool,buffer cache, java pool 和large pool。一般来说,当数据库需要分配一个大的对象到共享池中并且不能找到连续的可用空间,将自动使用其他SGA结构的空闲空间来增加共享池的大小 。既然空间分配是Oracle自动管理的,ora-4031出错的可能性将大大降低。自动内存管理在初始化参数SGA_TARGET大于0的时候被激活。当前设定可以通过查询v$sga_dynamic_components 视图获得。请参考10g管理手册以得到更多内容 。


2.诊断ORA-04031 错误

注:大多数的常见的 ORA-4031 的产生都和 SHARED POOL SIZE 有关,这篇文章中的诊断步骤大多都是关于共享池的。 对于其它方面如Large_pool或是Java_pool,内存分配算法都是相似的,一般来说都是因为结构不够大造成。

ORA-04031 可能是因为 SHARED POOL 不够大,或是因为碎片问题导致数据库不能找到足够大的内存块。ORA-04031 错误通常是因为库高速缓冲中或共享池保留空间中的碎片。 在加大共享池大小的时 候考虑调整应用,使用共享的SQL 并且调整如下的参数:


SHARED_POOL_SIZE,SHARED_POOL_RESERVED_SIZE,SHARED_POOL_RESERVED_MIN_ALLOC.

首先判定是否ORA-04031 错误是由共享池保留空间中的库高速缓冲的碎片产生的。提交下的查询:


SELECT free_space, avg_free_size,used_space, avg_used_size, request_failures, last_failure_size FROM v$shared_pool_reserved;

如果:

REQUEST_FAILURES > 0 并且 LAST_FAILURE_SIZE > SHARED_POOL_RESERVED_MIN_ALLOC

那么ORA-04031 错误就是因为共享池保留空间缺少连续空间所致。要解决这个问题,可以考虑加大SHARED_POOL_RESERVED_MIN_ALLOC 来降低缓冲进共 享池保留空间的对象数目,并增大 SHARED_POOL_RESERVED_SIZE 和 SHARED_POOL_SIZE 来加大共享池保留空间的可用内存。如果:

REQUEST_FAILURES > 0 并且 LAST_FAILURE_SIZE < SHARED_POOL_RESERVED_MIN_ALLOC
或者

REQUEST_FAILURES 等于0 并且 LAST_FAILURE_SIZE < SHARED_POOL_RESERVED_MIN_ALLOC

那么是因为在库高速缓冲缺少连续空间导致ORA-04031 错误。

第一步应该考虑降低SHARED_POOL_RESERVED_MIN_ALLOC 以放入更多的对象到共享池保留空间中并且加大SHARED_POOL_SIZE。

3.解决ORA-04031 错误


ORACLE BUG

Oracle推荐对你的系统打上最新的PatchSet。大多数的ORA-04031错误都和BUG 相关,可以通过使用这些补丁来避免。

下面表中总结和和这个错误相关的最常见的BUG、可能的环境和修补这个问题的补丁。 BUG 描述 Workaround Fixed
<Bug:1397603> ORA-4031/SGA memory leak of PERMANENT memory occurs for buffer handles _db_handles_cached = 0 901/ 8172
<Bug:1640583> ORA-4031 due to leak / cache buffer chain contention from AND-EQUAL access Not available 8171/901
<Bug:1318267> INSERT AS SELECT statements may

not be shared when they should be

if TIMED_STATISTICS. It can lead to ORA-4031

_SQLEXEC_PROGRESSION_COST=0
8171/8200
<Bug:1193003> Cursors may not be shared in 8.1

when they should be
Not available 8162/8170/ 901
<Bug:2104071> ORA-4031/excessive "miscellaneous" shared pool usage possible. (many PINS) None-> This is known to affect the XML parser. 8174, 9013, 9201
<Note:263791.1> Several number of BUGs related to ORA-4031 erros were fixed in the 9.2.0.5 patchset Not available 9205



编译Java代码时出现的ORA-4031

在你编译Java代码的时候如果内存溢出,你会看到错误:

A SQL exception occurred while compiling: : ORA-04031: unable to allocate bytes of shared memory ("shared pool","unknown object","joxlod: init h", "JOX: ioc_allocate_pal")

解决办法是关闭数据库然后把参数 JAVA_POOL_SIZE 设定为一个较大的值。这里错误信息中提到的 "shared pool" 其实共享全局区(SGA)溢出的误导,并不表示你需要增加SHARED_POOL_SIZE,相反,你必须加大 JAVA_POOL_SIZE 参数的值,然后重启动系统,再试一下。参考: <Bug:2736601> 。


小的共享池尺寸

很多情况下,共享池过小能够导致ORA-04031错误。下面信息有助于你调整共享池大小:

库高速缓冲命中率

命中率有助于你衡量共享池的使用,有多少语句需要被解析而不是重用。下面的SQL语句有助于你计算库高速缓冲的命中率:

SELECT SUM(PINS) "EXECUTIONS", SUM(RELOADS) "CACHE MISSES WHILE EXECUTING" FROM V$LIBRARYCACHE;

如果丢失超过1%,那么尝试通过加大共享池的大小来减少库高速缓冲丢失。

共享池大小计算

要计算最适合你工作负载的共享池大小,请参考:<Note:1012046.6>: HOW TO CALCULATE YOUR SHARED POOL SIZE.

共享池碎片

每一次,需要被执行的SQL 或者PL/SQL 语句的解析形式载入共享池中都需要一块特定的连续的空间。数据库要扫描的第一个资源就是共享池中的空闲可用内存。一旦空闲内存耗尽,数据库要查找一块已经分配但还没使用的内存准备重用。如果这样的确切尺寸的大块内存不可用,就继续按照如下标准寻找:

大块(chunk)大小比请求的大小大
空间是连续的
大块内存是可用的(而不是正在使用的)

这样大块的内存被分开,剩余的添加到相应的空闲空间列表中。当数据库以这种方式操作一段时间之后,共享池结构就会出现碎片。

当共享池存在碎片的问题,分配一片空闲的空间就会花费更多的时间,数据库性能也会下降(整个操作的过程中,"chunk allocation"被一个叫做"shared pool latch" 的闩所控制) 或者是出现 ORA-04031 错误errors (在数据库不能找到一个连续的空闲内存块的时候)。

参考 <Note:61623.1>: 可以得到关于共享池碎片的详细讨论。
如果SHARED_POOL_SIZE 足够大,大多数的 ORA-04031 错误都是由共享池中的动态SQL 碎片导致的。可能的原因如下:
非共享的SQL
生成不必要的解析调用 (软解析)
没有使用绑定变量

要减少碎片的产生你需要确定是前面描叙的几种可能的因素。可以采取如下的一些方法,当然不只局限于这几种: 应用调整、数据库调整或者实例参数调整。

请参考 <Note:62143.1>,描述了所有的这些细节内容。这个注释还包括了共享池如何工作的细节。

下面的视图有助于你标明共享池中非共享的SQL/PLSQL:

V$SQLAREA 视图

这个视图保存了在数据库中执行的SQL 语句和PL/SQL 块的信息。下面的SQL 语句可以显示给你带有literal 的语句或者是带有绑定变量的语句:

SELECT SUBSTR (sql_text, 1, 40) "SQL", COUNT (*), SUM (executions) "TotExecs" FROM v$sqlarea WHERE executions < 5GROUP BY SUBSTR (sql_text, 1, 40) HAVING COUNT (*) > 30ORDER BY 2;

注: Having 后的数值 "30" 可以根据需要调整以得到更为详细的信息。

X$KSMLRU 视图

这个固定表x$ksmlru 跟踪共享池中导致其它对象换出(age out)的应用。这个固定表可以用来标记是什么导致了大的应用。

如果很多对象在共享池中都被阶段性的刷新可能导致响应时间问题并且有可能在对象重载入共享池中的时候导致库高速缓冲闩竞争问题。

关于这个x$ksmlru 表的一个不寻常的地方就是如果有人从表中选取内容这个表的内容就会被擦除。这样这个固定表只存储曾经发生的最大的分配。这个值在选择后被重新设定这样接下来的大的分配可以被标记,即使它们不如先前的分配过的大。因为这样的重置,在查询提交后的结果不可以再次得到,从表中的输出的结果应该小心的保存。监视这个固定表运行如下操作:

SELECT * FROM X$KSMLRU WHERE ksmlrsiz > 0;

这个表只可以用SYS用户登录进行查询。

X$KSMSP 视图 (类似堆Heapdump信息)

使用这个视图能找出当前分配的空闲空间,有助于理解共享池碎片的程度。如我们在前面的描述,查找为游标分配的足够的大块内存的第一个地方是空闲列表( free list)。 下面的语句显示了空闲列表中的大块内存:

SELECT '0 (<140)' bucket, ksmchcls, 10 * TRUNC (ksmchsiz / 10) "From", COUNT (*) "Count", MAX (ksmchsiz) "Biggest", TRUNC (AVG (ksmchsiz)) "AvgSize", TRUNC (SUM (ksmchsiz)) "Total" FROM x$ksmsp WHERE ksmchsiz < 140 AND ksmchcls = 'free'GROUP BY ksmchcls, 10 * TRUNC (ksmchsiz / 10)UNION ALLSELECT '1 (140-267)' bucket, ksmchcls, 20 * TRUNC (ksmchsiz / 20), COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize", TRUNC (SUM (ksmchsiz)) "Total" FROM x$ksmsp WHERE ksmchsiz BETWEEN 140 AND 267 AND ksmchcls = 'free'GROUP BY ksmchcls, 20 * TRUNC (ksmchsiz / 20)UNION ALLSELECT '2 (268-523)' bucket, ksmchcls, 50 * TRUNC (ksmchsiz / 50), COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize", TRUNC (SUM (ksmchsiz)) "Total" FROM x$ksmsp WHERE ksmchsiz BETWEEN 268 AND 523 AND ksmchcls = 'free'GROUP BY ksmchcls, 50 * TRUNC (ksmchsiz / 50)UNION ALLSELECT '3-5 (524-4107)' bucket, ksmchcls, 500 * TRUNC (ksmchsiz / 500), COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize", TRUNC (SUM (ksmchsiz)) "Total" FROM x$ksmsp WHERE ksmchsiz BETWEEN 524 AND 4107 AND ksmchcls = 'free'GROUP BY ksmchcls, 500 * TRUNC (ksmchsiz / 500)UNION ALLSELECT '6+ (4108+)' bucket, ksmchcls, 1000 * TRUNC (ksmchsiz / 1000), COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize", TRUNC (SUM (ksmchsiz)) "Total" FROM x$ksmsp WHERE ksmchsiz >= 4108 AND ksmchcls = 'free'GROUP BY ksmchcls, 1000 * TRUNC (ksmchsiz / 1000);


4. ORA-04031 错误与 Large Pool

大池是个可选的内存区,为以下的操作提供大内存分配:

MTS会话内存和 Oracle XA 接口
Oracle 备份与恢复操作和I/O服务器进程用的内存(缓冲)
并行执行消息缓冲
大池没有LRU列表。这和共享池中的保留空间不同,保留空间和共享池中其他分配的内存使用同样的LRU列表。大块内存从不会换出大池中,内存必须是显式的被每个会话分配并释放。一个请求如果没有足够的内存,就会产生类似这样的一个ORA-4031错误:


ORA-04031: unable to allocate XXXX bytes of shared memory ("large pool","unknown object","session heap","frame")

这个错误发生时候可以检查几件事情:

1- 使用如下语句检查 V$SGASTAT ,得知使用和空闲的内存:

SELECT pool,name,bytes FROM v$sgastat where pool = 'large pool';

2- 你还可以采用 heapdump level 32 来 dump 大池的堆并检查空闲的大块内存的大小

从大池分配的内存如果是LARGE_POOL_MIN_ALLOC 子节的整块数有助于避免碎片。任何请求分配小于LARGE_POOL_MIN_ALLOC 大块尺寸都将分配LARGE_POOL_MIN_ALLOC的大小。一般来说,你会看到使用大池的时候相对共享池来说要用到更多的内存。通常要解决大池中的ORA-4031错误必须增加 LARGE_POOL_SIZE 的大小。


5. ORA-04031 和共享池刷新

有一些技巧会提高游标的共享能力,从而共享池碎片和ORA-4031都会减少。最佳途径是调整应用使用绑定变量。另外在应用不能调整的时候考虑使用CURSOR_SHARING参数和FORCE不同的值来做到 (要注意那会导致执行计划改变,所以建议先对应用进行测试)。当上述技巧都不可以用的时候,并且碎片问题在系统中比较严重,刷新共享持可能有助于减轻碎片问题。但是,必须加以如下考虑:

刷新将导致所有没被使用的游标从共享池删除。这样,在共享池刷新之后,大多数SQL和PL/SQL游标必须被硬解析。这将提高CPU的使用,也会加大Latch的活动。
当应用程序没有使用绑定变量并被许多用户进行类似的操作的时候(如在OLTP系统中) ,刷新之后很快还会出现碎片问题。所以共享池对设计糟糕的应用程序来说不是解决办法。
对一个大的共享池刷新可能会导致系统挂起,尤其是实例繁忙的时候,推荐在非高峰的时候刷新

6. ORA-04031错误的高级分析

如果前述的这些技术内容都不能解决ORA-04031 错误,可能需要额外的跟踪信息来得到问题发生的共享池的快照。

调整init.ora参数添加如下的事件得到该问题的跟踪信息:

event = "4031 trace name errorstack level 3" event = "4031 trace name HEAPDUMP level 3" 如果问题可重现,该事件可设定在会话层,在执行问题语句之前使用如下的语句:

SQL> alter session set events '4031 trace name errorstack level 3'; SQL> alter session set events '4031 trace name HEAPDUMP level 3'; 把这个跟踪文件发给Oracle支持人员进行排错。

重要标注: Oracle 9.2.0.5 和Oracle 10g 版本中,每次在发生ORA-4031 错误的时候会自动创建一个跟踪文件,可以在user_dump_dest 目录中找到。如果你的系统是上述的版本,你不需要再进行前面描述中的步骤。
分享到:
评论

相关推荐

    Oracle数据库发生ORA-04031错误原因浅析及处理.pdf

    Oracle数据库发生ORA-04031错误原因浅析及处理 Oracle数据库是甲骨文公司提供的...本文通过对ORA-04031错误的分析和解决方法的介绍,旨在帮助读者更好地理解Oracle数据库中的ORA-04031错误,并提供了实用的解决方法。

    ORA-04031故障分析处理

    解决ORA-04031错误通常涉及调整参数,优化内存分配策略,以及监控和分析数据库的运行状况。在ASM实例中,由于其特殊性,可能需要更大的共享池大小来满足存储管理和查询的需求。在调整参数时,应谨慎操作并进行充分的...

    如何解决Oracle 常见错误 ORA-04031(PDF)

    ### 如何解决Oracle常见错误 ORA-04031 #### 一、与共享池相关的实例参数 在深入探讨如何解决ORA-04031错误之前,我们...通过上述方法,可以有效地诊断并解决ORA-04031错误,从而提高Oracle数据库的性能和稳定性。

    创建物化视图ORA-12014错误解决方法

    ### 创建物化视图ORA-12014错误解决方法 #### 背景介绍 在Oracle数据库中,物化视图(Materialized View)是一种用于优化查询性能的重要工具。它预先计算并存储了复杂的查询结果,从而在实际查询时能够快速地返回...

    ora-01033错误解决方法

    ### ORA-01033 错误解决方法 #### 概述 在数据库管理过程中,遇到诸如ORA-01033等错误代码是非常常见的。这些错误往往与数据库实例的状态、文件系统问题或是配置不当有关。ORA-01033 错误通常表示在启动或关闭...

    Drop goldengate用户时报ORA-00604 ORA-20782 ORA-06512问题解决

    #### 二、错误分析及处理步骤 **1. 错误现象** 执行`drop user goldengate cascade;`时,系统返回以下错误信息: ``` ERROR at line 1: ORA-00604: error occurred at recursive SQL level 2 ORA-20782: Oracle ...

    Oracle 10g启动后报ORA-16038错误的解决方法

    ### Oracle 10g启动后报ORA-16038错误的解决方法 #### 错误概述 在启动Oracle 10g数据库时遇到ORA-16038错误,该错误通常与归档日志操作有关。具体错误信息为: ``` ORA-16038: log 1 sequence #230 cannot be ...

    数据库ORA-01460错误的解决方法

    虽然这不是直接解决ORA-01460错误的方法,但通过合理配置工具和环境,可以更高效地进行数据库管理和数据转换工作,间接降低错误发生的概率。 总之,面对ORA-01460错误,关键在于理解错误背后的逻辑,采取合适的数据...

    ora-01460 错误原因分析

    ### ORA-01460 错误原因分析 #### 概述 在Oracle数据库操作过程中,可能会遇到ORA-01460错误,该错误全称为“ORA-01460: 转换请求无法实现或不合理”。这一错误通常发生在数据类型转换或者与操作系统之间的数据...

    ora-227101错误解决办法

    在Oracle数据库管理与维护的过程中,遇到各种错误代码是家常便饭,其中“ORA-227101”错误虽然在题目...通过以上分析和解决方案,可以有效地应对和解决Oracle数据库中ORA-27101及相关错误,确保数据库服务的稳定运行。

    ORACLE8I数据库应用EXP工具时ORA-06553报错的解决方法.pdf

    摘要:本文主要解决ORACLE 8I数据库应用EXP工具时ORA-06553报错的问题,分析出现问题的原因,并提供了正确的解决方法和措施。 知识点1:Oracle 8I数据库EXP工具的应用 Oracle 8I数据库EXP工具是Oracle数据库提供...

    ORA-12514错误解决办法

    ### ORA-12514错误解决办法 #### 错误概述 ORA-12514是Oracle数据库中常见的一个错误,全称为“TNS:listener does not currently know of service requested in connect descriptor”。该错误表明客户端尝试连接到...

    离线误删空间文件导致的ORA-01033及ORA-01145问题的解决办法

    ### 离线误删空间文件导致的ORA-01033及ORA-01145问题的解决办法 #### 概述 在Oracle数据库管理过程中,偶尔会遇到因误操作导致的数据文件出现问题的情况,例如误删除数据文件或者数据文件损坏等。这些问题可能会...

    如何处理错误ORA-29275:部分多字节字符

    通过以上方法,我们可以有效地解决ORA-29275错误,并提高Oracle数据库的整体稳定性和数据完整性。需要注意的是,在实际操作过程中,应当根据具体情况选择最适合的解决方案。例如,在某些情况下,调整字段长度可能是...

    如何解决Oracle数据库中的04031错误

    总之,解决ORA-04031错误需要深入理解Oracle内存管理机制,仔细诊断问题所在,并采取适当的调整措施。这可能涉及参数调整、SQL优化以及对数据库整体架构的审查。通过以上步骤,可以有效地避免和解决这种常见的Oracle...

    oracle ora-03113错误

    ### Oracle ORA-03113 错误解析及解决方法 #### 一、ORA-03113 错误概述 ORA-03113 是一个较为常见的Oracle错误,通常出现在网络通信出现问题时,具体表现为“end-of-file on communication channel”(通信通道上...

    oracle重启报错ORA-00702解决办法

    本文将详细介绍如何在Windows和Linux操作系统下解决ORA-00702错误。 **ORA-00702错误解析** ORA-00702错误信息表明数据库实例试图访问一个尚未完全初始化的数据文件或控制文件。这可能是由于数据库在不正常的情况下...

    Oracle_ORA-12518故障_处理

    本文旨在详细介绍ORA-12518错误的成因、常见表现形式以及具体的故障排查方法,以帮助读者在实际工作中能够更高效地解决这一问题。 #### 目的 本文旨在探讨如何接近并解决ORA-12518/TNS-12518错误,并提供详细的...

    ERwin连接oracle报ORA-01041内部错误,hostdef扩展名不存在.docx

    根据提供的部分内容,下面详细介绍解决ORA-01041错误的具体步骤: 1. **启动Oracle配置和移植工具** - 打开Oracle的“配置和移植工具”中的“Net Configuration Assistant”。 2. **本地网络服务名配置** - 在...

    ORACLE出现ORA-15414错误

    根据提供的描述,“登陆oracle时出现ora-15414时按照文档操作即可安全无压力”,我们可以推测此错误与配置文件`listener.ora`有关,并且可以通过调整该文件来解决。 #### ORA-15414错误含义 ORA-15414是Oracle...

Global site tag (gtag.js) - Google Analytics