ORA-04031的产生原因及解决方法

现象:ORA-04031: unable to allocate 4096 bytes of shared memory

具体原因及解决方法:

ORA-04031出现的问题有以下几个可能性:

1. 没有绑定编量造成shared_pool碎片过多,同时shared_pool_size太小

(1)这个情况是比较常见的。

(2)第二种情况通常会建议使用绑定变量,或者用简单的加大shared_pool,临时的解决方法就是alter system flush shared_pool。

2. Large_pool,Java_pool太小造成的

(1)这个通过错误信息的提示很容易判断(Ora-04031 cannot allocate .. memeory in [large_pool])

(2)解决方法就是简单的加大 Large_pool or Java_pool

3. 过度的开CURSOR而不关闭。

目前,此问题发生的越来越多,特别是在JAVA的运行环境中,屡见不鲜。加大Shared_pool或者flush shared_pool往往只能延迟问题出现的时间,而无法避免此问题。

判断方法:

select count(*) from v$open_cursor ;
select * from v$sysstat 
where name = 'opened cursors current';

假如出来的值特大(以万为单位)时,基本就可以确定是这个原因了。

解决这个问题的方法就是检查程序,看是否没有正常的关闭cursor(对于JAVA来说,就是没有关闭Statement)。或者select sql_text from v$open_cursor,看看都是哪些cursor没关闭,再去检查车程序。

也有的程序使用了保持一定量的cursor一直open,从而避免cursor过多次的开启,来提高性能。对于这种情况,则应该选择适当的shared_pool_size和控制keep_opening的cursor的量。

另外,Oracle参数session_cached_cursors也有可能过大,解决的方法就是把它降低到适当的值。

参考:

编译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 参数的值,然后重启动系统,再试一下。参考: 。
  
  小的尺寸
  
  很多情况下,过小能够导致ORA-04031错误。下面信息有助于你调整大小:
  
  库高速缓冲命中率
  
  命中率有助于你衡量的使用,有多少语句需要被解析而不是重用。下面的SQL语句有助于你计算库高速缓冲的命中率:
  
  SELECT SUM(PINS) "EXECUTIONS",
  SUM(RELOADS) "CACHE MISSES WHILE EXECUTING"
  FROM V$LIBRARYCACHE;
  
  如果丢失超过1%,那么尝试通过加大的大小来减少库高速缓冲丢失。
  
  大小计算
  
  要计算最适合你工作负载的大小,请参考:
  
  : HOW TO CALCULATE YOUR SHARED POOL SIZE.
  
  碎片
  
  每一次,需要被执行的SQL 或者PL/SQL 语句的解析形式载入中都需要一块特定的连续的空间。数据库要扫描的第一个资源就是中的空闲可用内存。一旦空闲内存耗尽,数据库要查找一块已经分配但还没使用的内存准备重用。如果这样的确切尺寸的大块内存不可用,就继续按照如下标准寻找:
  
  大块(chunk)大小比请求的大小大
  
  空间是连续的
  
  大块内存是可用的(而不是正在使用的)
  
  这样大块的内存被分开,剩余的添加到相应的空闲空间列表中。当数据库以这种方式操作一段时间之后,结构就会出现碎片。
  
  当存在碎片的问题,分配一片空闲的空间就会花费更多的时间,数据库性能也会下降(整个操作的过程中,"chunk allocation"被一个叫做"shared pool latch" 的闩所控制) 或者是出现 ORA-04031 错误errors (在数据库不能找到一个连续的空闲内存块的时候)。
  
  参考 : 可以得到关于碎片的详细讨论。
  
  如果SHARED_POOL_SIZE 足够大,大多数的 ORA-04031 错误都是由中的动态SQL 碎片导致的。可能的原因如下:
  
  非的SQL
  
  生成不必要的解析调用 (软解析)
  
  没有使用绑定变量
  
  要减少碎片的产生你需要确定是前面描叙的几种可能的因素。可以采取如下的一些方法,当然不只局限于这几种: 应用调整、数据库调整或者实例参数调整。
  
  请参考 ,描述了所有的这些细节内容。这个注释还包括了如何工作的细节。
  
  下面的视图有助于你标明中非的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 < 5
  GROUP BY SUBSTR (sql_text, 1, 40)
  HAVING COUNT (*) > 30
  ORDER 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 ALL
  SELECT  '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 ALL
  SELECT  '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 ALL
  SELECT  '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 ALL
  SELECT  '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 目录中找到。如果你的系统是上述的版本,你不需要再进行前面描述中的步骤。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14075938/viewspace-474727/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14075938/viewspace-474727/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ORA-01453是Oracle数据库的一个错误代码,表示在执行SQL语句时,发现了一个无效的行限制(row limit)。 当在SELECT语句中使用ROWNUM或FETCH FIRST或OFFSET子句来限制返回的行数时,可能会发生这个错误。例如,下面的SQL查询就可能导致ORA-01453错误: ``` SELECT * FROM my_table WHERE ROWNUM <= 10; ``` 如果my_table表中的行数少于10行,则查询不会出错。但如果my_table表中的行数超过10行,则Oracle会尝试在返回前10行数据时应用ROWNUM限制,这时就会产生ORA-01453错误。 此外,该错误也可能在使用FETCH FIRST或OFFSET子句时出现,例如: ``` SELECT * FROM my_table ORDER BY some_column OFFSET 10 ROWS; ``` 如果my_table表中的行数不足10行,则查询不会出错。但如果my_table表中的行数不足10行,则Oracle会尝试返回第11行数据,这时就会产生ORA-01453错误。 ### 回答2: ORA-01453错误是由于试图修改包含只读表的视图或临时表造成的。它表示用户试图执行不允许的更新操作,因为操作的对象是只读的。 这个错误通常发生在以下情况下: 1. 用户试图在只读表上执行INSERT,UPDATE或DELETE操作。 2. 用户试图修改包含只读表的视图。 3. 用户试图修改包含只读表的临时表。 在这些情况下,Oracle数据库会自动检测到用户试图进行的非法操作,并抛出ORA-01453错误。 要解决这个错误,可以采取以下措施: 1. 确保只对允许修改的表执行INSERT,UPDATE或DELETE操作。 2. 检查视图或临时表的定义,确保它们没有包含只读表。 3. 如果需要对只读表进行修改,可以考虑修改表的权限或复制表数据到可修改的表中。 总的来说,ORA-01453错误是由于试图修改只读表造成的。了解引起该错误的常见情况和解决方法可以帮助我们避免或解决这个问题。 ### 回答3: ORA-01453错误是Oracle数据库中的一个常见错误,它表示插入或更新操作违反了唯一约束条件。 当我们在执行插入或更新操作时,如果涉及到的列设置了唯一约束(如PRIMARY KEY或UNIQUE约束),那么数据库会检查操作是否会导致数据重复。如果操作导致的数据与已存在的数据重复,就会产生ORA-01453错误。 具体来说,ORA-01453错误可能有以下几种情况: 1. 插入操作:当我们尝试将一条新的记录插入到表中,而该记录的唯一约束列与表中已经存在的记录的唯一约束列重复时,就会产生ORA-01453错误。 2. 更新操作:当我们尝试更新表中的记录,而更新后的记录的唯一约束列与其他记录的唯一约束列重复时,就会产生ORA-01453错误。 在实际应用中,我们可以通过以下方式来解决ORA-01453错误: 1. 检查数据:首先,我们需要检查在插入或更新操作中涉及的数据是否重复。如果是由于数据问题导致的错误,我们需要确保准备好的数据是唯一的。 2. 查找重复数据:在遇到ORA-01453错误后,我们可以使用SELECT语句来查找重复的数据行,并对其进行处理。可以通过删除重复的记录、更新记录或更改约束来解决重复数据的问题。 3. 修改约束:如果确定了数据不是问题所在,我们可以考虑修改相关的约束条件,以避免出现ORA-01453错误。 总之,ORA-01453错误是由于插入或更新操作违反了唯一约束条件而产生的。通过检查数据、查找重复数据和修改约束,我们可以解决这个错误并确保数据的完整性和唯一性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值