【DB笔试面试683】在Oracle中,什么是ORA-01555错误?

小编:啊南 345阅读 2020.12.03

题目部分

在Oracle中,什么是ORA-01555错误?

答案部分

在告警日志中记录的ORA-01555(snapshot too old,快照过旧)报错信息类似:

ORA-01555: snapshot too old: rollback segment number 107 with name "_SYSSMU107_1253191395$" too small

默认情况,ORA-01555错误发生时不会自动生成跟踪日志文件,但是可以在系统里设置下面的事件,让它在错误发生时同时生成跟踪日志文件:

alter system set events '1555 trace name errorstack level 3';

由于回滚段是循环使用的,当事务提交以后,该事务占用的回滚段事务会被标记为非活动,此时的回滚段空间可以被覆盖重用。那么问题就出现了,如果一个查询需要使用被覆盖的回滚段构造前镜像(Before Image)实现一致性读,那么此时就会出现Oracle著名的ORA-01555(snapshot too old,快照过旧)错误。需要注意的是,ORA-01555错误是一个安全的错误,它不会造成数据丢失或者损坏,只是会让收到该错误的查询无法继续。

ORA-01555错误的另外一个原因是延迟块清除(Delayed Block Clean out)。当一个查询触发延迟块清除时,Oracle需要去查询回滚段获得该事务的提交SCN。如果事务的前镜像(Before Image)信息已经被覆盖,并且查询SCN也小于回滚段中记录的最小提交SCN,那么Oracle将无从判断查询SCN和事务提交SCN的大小,此时出现延迟块清除会导致ORA-01555错误。

还有一种导致ORA-01555错误的情况出现在使用SQL*Loader直接方式加载(direct=true)数据时,由于不产生Redo和Undo信息,Oracle直接指定CACHED COMMIT SCN进行加载数据,在访问这些数据时,有时会产生ORA-01555错误。

知道了ORA-01555错误产生的原因就可以总结出以下方法来解决ORA-01555错误问题:

(1)扩大回滚段

因为回滚段是循环使用的,如果回滚段足够大,那么那些被提交的数据信息就能保存足够长的时间,而那些大事务就可以完成一致性读取。

(2)增加UNDO_RETENTION时间

在UNDO_RETENTION规定的时间内,任何其它事务都不能覆盖这些数据。

(3)优化相关查询语句,减少一致性读

减少查询语句的一致性读,也可以降低读取不到回滚段数据的风险。

(4)减少不必要的事务提交

提交的事务越少,产生的回滚段信息就越少。

(5)对大事务指定回滚段

通过以下语句可以指定事务的回滚段:

SET TRANSACTION USE ROLLBACK SEGMENT rollback_segment;

给大事务指定回滚段,即降低大事务回滚信息覆盖其它事务的回滚信息的几率,又降低了它自身的回滚信息被覆盖的几率。大事务的存在,往往是ORA-01555错误产生的诱因。

(6)使用游标时尽量使用显式游标,并且只在需要的时候打开游标,同时将所有可以在游标外做的操作从游标循环中拿出。当游标打开时,查询就开始了,直到游标关闭。减少游标的打开时间,就减少了ORA-01555错误发生的几率。

(7)使用回滚表空间自动管理

回滚表空间自动管理是Oracle 9i后的特性,Oracle自动管理回滚段的创建和回收,并且Oracle 10g中,这一特性大大增强了,而在大型的数据仓库或者报表系统中,会有一些很大的查询作业存在,这时可以考虑使用手动管理,为某些大作业创建单独的回滚段。

关联标签: