oracle redo与undo_笔记9:ORA-01555:snapshot too old错误
ORA-01555:snapshot too old错误
ORA-01555与数据破坏或数据丢失毫无关系。在这方面,这是一个“安全”的错误,唯一的影响是:接收到这个错误的查询无法继续处理。
这个错误实际上很直接,其实只有两个原因,但是其中之一有一个特例,而且这种特例情况发生得如此频繁,所以存在以下3个原因。
.undo段太小,不足以在系统上执行工作
.程序跨COMMIT获取(实际上这是前一点的一个变体)
.块清除
查询的结果是预定的,这说明在Oracle去获取第一行之前,结果就已经定好了。Oracle使用undo段来回滚自查询开始以来有修改的块。从而提供数据的一致时间点“快照”。例如执行以下语句:
update t set x=5 where x=2;
insert into t select * from t where x=2;
delete from t where x=2;
select * from t where x=2;
执行每条语句都会看到T的一个读一致视图以及x=2的行集,而不论数据库中还有哪些并发的活动。
所有“读”这个表的语句都利用了这种读一致性。在上面所示的例子中,UPDATE读这个表,找到X=2的行(然后更新这些行)。INSERT也要读表,找到X=2的行,然后插入,等等。由于两个语句都使用了undo段,都是为了回滚失败的事务并提供读一致性,这就导致了ORA-01555错误。
ORA-01555错误的几种解决方案,一般来说可以采用下面的方法。
.适当地设置参数UNDO_RETENTION(要大于执行运行时间最长的事务所需的时间)。可以用V$UNDOSTAT UNDOSTAT来确定长时间运行的查询的持续时间。另外,要确保磁盘上已经预留了足够的空间,使UNDO段能根据所请求的UNDO_RETENTION增大。
.使用手动UNDO管理时加大或增加更多的回滚段。这样在长时间运行的查询执行期间,覆盖undo数据的可能性就能能降低。这种方法可以解决上述的所有3个问题。请注意,不要将此方法作为首选方法。强烈建议采用自动undo管理。
.减少查询的运行时间(调优)。如果可能的话,这绝对是一个好办法,所以应该首先尝试这种方法。这样就能降低对undo段的需求,不需要太大的undo段。这种方法可以解决上述的所有3个问题。
.收集相关对象的统计信息。这有助于避免前面所列的第三点。由于大批量的UPDATE或INSERT会导致块清除(block cleanout),所以需要在大批量UPDATE或大量加载之后以某种方式收集统计信息。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5270.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
