ITPub博客

首页 > 数据库 > Oracle > 关于ORA-01555

关于ORA-01555

原创 Oracle 作者:empo007 时间:2008-05-19 16:14:26 0 删除 编辑
工作中经常会遇到错误ORA-01555,结合工作中的经验,参考几篇ORACLE文档,下面进行一下总结。[@more@]

一、ORA-01555错误发生的两个原因
原因之一是回滚段太小、回滚段数目少导致回滚段中的相关数据块被overwritten
原因之二是延迟块清除
如果一个会话对某个表进行了大量更新,oracle并不是马上去回写数据块并清除块的事务信息,而是在下次访问这些块的时候进行这些操作。这样事务信息在延迟清除之前的状态是:在数据块头有未提交事务的相关回滚段、事务槽的信息,而对应回滚段头对应事务槽的状态为committed,当下一次数据块被访问到的时候,会话发现该块是uncommitted,就会去找相关的回滚段。因为相关事务槽的状态为committed,如果该回滚段上的事务非常多,那么该事务槽可能会被overwritten。这样ORACLE可能无法找到它需要的块,从而出现ORA-01555错误。
二、自动undo管理是如何使用extent的?
1、当undo信息被写入UNDO段,如果超过了当前extent的底端,并且发现下一个extent里面的undo是过期的,那么undo就会被写入这个过期的extent,否则将从undo表空间中分配一个新的extent.
2、如果上面的步骤失败,oracle就会从其它undo段中steal一个过期的extent.
3、如果第二步也失败,那么ORACLE就会重用当前UNDO段的没有过期的extent.
4、如果还是失败,那么ORACLE就会从其它undo段中steal一个没有过期的extent.
5、如果上面的步骤都失败,那么oracle就会报空间不足的错误
三、视图v$undostat
BEGIN_TIME - The beginning time for this interval check
END_TIME - The ending time for this interval check
UNDOTSN - The undo tablespace number
UNDOBLKS - The total number undo blocks consumed during the time interval
TXNCOUNT - The total number of transactions during the interval
MAXQUERYLEN - The maximum duration of a query within the interval
MAXCONCURRENCY - The highest number of transactions during the interval
UNXPSTEALCNT - The number of attempts when unexpired blocks were stolen from other undo segments to satisfy space requests
UNXPBLKRELCNT - The number of unexpired blocks removed from undo segments to be used by other transactions
UNXPBLKREUCNT - The number of unexpired undo blocks reused by transactions
EXPSTEALCNT - The number of attempts when expired extents were stolen from other undo segments to satisfy a space requests
EXPBLKRELCNT - The number of expired extents stolen from other undo segments to satisfy a space request
EXPBLKREUCNT - The number of expired undo blocks reused within the same undo segments
SSOLDERRCNT - The number of ORA-1555 errors that occurred during the interval
NOSPACEERRCNT - The number of Out-of-Space errors
四、如何troubleshoot
需要考虑的几个问题:
1、因为LOB对象的UNDO信息是存放在对象所在的segment里面的,所以首先应检查是否包含lob列,如果是LOB列导致了该错误,那么需要增大相关pctversion.
2、RAC环境下,需要确定相关回滚段是属于哪个实例:
select stat.inst_id,seg.segment_name,seg.tablespace_name
from dba_rollback_segs seg,gv$rollstat stat
where seg.segment_id=stat.usn
and seg.segment_name='';
3、下面的语句可以帮助我们了解到底是空间不足还是超出undo_retention导致了ora-01555错误:
set pagesize 25
set linesize 100

column UNXPSTEALCNT heading "# Unexpired|Stolen"
column EXPSTEALCNT heading "# Expired|Reused"
column SSOLDERRCNT heading "ORA-1555|Error"
column NOSPACEERRCNT heading "Out-Of-space|Error"
column MAXQUERYLEN heading "Max Query|Length"

select inst_id, to_char(begin_time,'MM/DD/YYYY HH24:MI') begin_time, UNXPSTEALCNT,

EXPSTEALCNT , SSOLDERRCNT, NOSPACEERRCNT, MAXQUERYLEN
from gv$undostat
where begin_time between to_date('','MM/DD/YYYY HH24:MI:SS')
and to_date('','MM/DD/YYYY HH24:MI:SS')
order by inst_id, begin_time;

下面的情况说明undo_retention太小了:
# Unexpired # Expired ORA-1555 Out-Of-space Max Query
INST_ID BEGIN_TIME Stolen Reused Error Error Length
------- ---------------- ----------- ---------- ---------- ------------ ----------
...
1 08/28/2006 10:20 0 0 0 0 5852
1 08/28/2006 10:30 0 0 0 0 6252
1 08/28/2006 10:40 0 0 0 0 6852
1 08/28/2006 10:50 0 32 0 0 7452
1 08/28/2006 11:00 0 7 1 0 8212

下面的情况说明UNDO表空间空间不够:

# Unexpired # Expired ORA-1555 Out-Of-space Max Query
INST_ID BEGIN_TIME Stolen Reused Error Error Length
------- ---------------- ----------- ---------- ---------- ------------ ----------
...
1 08/28/2006 10:20 0 0 0 0 1
1 08/28/2006 10:30 0 0 0 0 1
1 08/28/2006 10:40 0 0 0 0 1
1 08/28/2006 10:50 23 0 0 0 272
1 08/28/2006 11:00 67 0 1 1 843

RAC环境下:

# Unexpired # Expired ORA-1555 Out-Of-space Max Query
INST_ID BEGIN_TIME Stolen Reused Error Error Length
------- ---------------- ----------- ---------- ---------- ------------ ----------
1 08/28/2006 14:58 0 0 0 0 8111
1 08/28/2006 15:08 0 0 0 0 8711
1 08/28/2006 15:18 0 0 1 0 9245
2 08/28/2006 15:04 0 13 0 0 1020
2 08/28/2006 15:14 17 16 0 1 1020
2 08/28/2006 15:24 0 0 0 0 1020
这个例子说明因实例2的UNDO表空间空间不足导致实例一上出现ORA-01555错误
五、几个CASE
1、回滚段太少、太小
对于数据改变比较频繁的数据库,重用已经提交事务所使用空间的可能性比较大,那么一个长时间运行的查询可能就不能重建相关的数据块,从而导致错误发生。
2、回滚段被损坏
如果相关块被损坏,当然也就不可能重建相关块
3、fetch across commit
这种情况是:先打开一个游标,然后进入循环,循环体中对同一个表进行更改,提交,这种情况很容易发生ORA-01555错误
4、Fetch across commits with delayed block clean out
这种情况下最好在fetch之前执行一次全表扫描清除相关块的事务信息

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

请登录后发表评论 登录
全部评论
  • 博文量
    126
  • 访问量
    1098960