ORA-01555原因及解决方案

ORA-01555 原因与解决:

前面提到了ORA-01555错误,那么现在来看一下ORA-01555错误是怎样产生的。由于回滚段是循环使用的,当事务提交以后,该事务占用的回滚段事务会被标记为非活动,回滚段空间可以被覆盖重用。那么一个问题就出现了,如果一个查询需要使用被覆盖的回滚段构造前镜像实现一致性读,那么此时就会出现Oracle著名的ORA-01555错误。

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

另外一种导致ORA-01555错误的情况出现在使用sqlldr直接方式加载(direct=true)数据时。当通过sqlldr direct=true 方式加载数据时,由于不产生重做和回滚信息,Oracle直接指定Cached Commit SCN 给加载数据,在访问这些数据时,有时会产生ORA-01555错误。

看下图的描述:假定在时间T用户A发出一条更新语句,更新SCOTT用户的SAL;用户B在Ty时间发出查询语句,查询SCOTT用户的SAL;用户A的更新在Tx时间提交,提交可能为快速提交块清除,也可能是延迟块清除;用户B的查询在Tz时间输出。

来看一下数据库在不同情况下的内部处理:

·如果 Ty < T < Tz < Tx ,那么查询需要构造一致性读,由于事务尚未提交,可以通过回滚段构造前镜像,完成一致性读取。
·如果 Ty < T < Tx < Tz ,由于Ty查询时间小于T事务更新时间,那么数据库需要构造一致性读取,而Tz查询完成时间大于Tx提交时间,那么前镜像就有可能被覆盖,不可获取。

如果Tx的提交方式为Fast Block Cleanout,那么回滚段信息不可用时就会出现一致性读ORA-01555错误。

如果Tx的提交方式为Delayed Block Cleanout,那么回滚段信息不可用时Oracle将无法判断Ty和Tx的时间先后关系。如果 Ty > Tx ,那么Oracle可以正常进行块清除,并将块清除后的数据返回给用户B;如果 Ty < T ,那么Oracle需要继续构造一致性读返回给用户B;Oracle无法判断这两种情况,就会出现延迟块清除ORA-01555错误。

ORA-01555的直观解释是“snapshot too old”,也就是快照太旧,其根本含义就是查询需要的前镜像过于“久远”,已经无法找到了。可以想象,如果一个历时数个小时或十几个小时的查询,如果最后遭遇ORA-01555错误而失败,会是多么令人沮丧的一件事。一直以来,ORA-01555都是ORACLE最为头痛的问题之一。

在Oracle 9i的文档中这样描述ORA-01555错误:

01555, 00000, "snapshot too old: rollback segment number %s with name \"%s\" too small"
// *Cause: rollback records needed by a reader for consistent read are
//         overwritten by other writers
// *Action: If in Automatic Undo Management mode, increase undo_retention
//          setting. Otherwise, use larger rollback segments

可以看到,在Oracle 9i自动管理UNDO表空间模式下,UNDO_RETENTION参数的引入正是为了减少ORA-01555错误的出现。这个参数设置当事务提交之后(回滚段变得非活跃),回滚段中的前镜像数据在被覆盖前保留的时间,该参数以秒为单位,9iR1初始值为900秒,在Oracle 9iR2增加为10800秒。

显然该参数设置的越高就越能减少ORA-01555错误的出现,但是保留时间和存储空间是紧密相关的,如果UNDO表空间的存储空间有限,那么Oracle就会选择回收已提交事务占用的空间,置UNDO_RETENTION参数于不顾。

在Oracle 9i的AUM模式下,UNDO_RETENTION实际上是一个非担保(NO Guaranteed)限制。也就是说,如果有其他事务需要回滚空间,而空间出现不足时,这些信息仍然会被覆盖;从Oracle 10g开始,Oracle对于UNDO增加了Guarantee控制,也就是说,可以指定UNDO表空间必须满足UNDO_RETENTION的限制。当UNDO表空间设置为Guarantee,那么提交事务的回滚空间必须被保留足够的时间,如果UNDO表空间的空间不足,那么新的事务会因空间不足而失败,而不是选择之前的覆盖。

从各个不同版本回滚段的管理变迁,我们可以看出Oracle一直在进步。

Oracle提供了一个内部事件(10203事件)可以用来跟踪数据库的块清除操作,10203事件可以通过以下命令设置,设置后需要重新启动数据库该参数方能生效:

alter system set event="10203 trace name context forever" scope=spfile;

需要注意的是,可能存在另外一种情况,就是当执行延迟块清除时,回滚段或原回滚表空间已经被删除,此时Oracle仍然可以通过字典表UNDO$来获得SCN信息,执行块清除。

关于Oracle的提交处理及块清除机制是一个极其复杂的过程,本文对这部分内容进行了适当简化说明,旨在使大家能够对Oracle的回滚机制、块清除机制有所了解。

- The End -

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
kettle ora-01555是指在使用kettle工具进行数据抽取或转换时,出现了Oracle数据库ORA-01555错误。ORA-01555错误是Oracle数据库的一个常见错误,也被称为Snapshot too old错误。 ORA-01555错误是由于事务回滚段中的数据被其他事务重用或者已经被覆盖而导致的。这种情况通常发生在并发事务环境下,当一个事务需要读取某些数据,但是在读取期间该数据已经被其他事务修改或删除,导致该事务无法读取到所需的数据而出现ORA-01555错误。 在kettle中,当进行数据抽取或转换时,kettle会同时执行多个SQL语句以读取或修改数据库中的数据。如果在执行这些SQL语句的过程中,有其他事务修改了这些数据,那么就有可能导致ORA-01555错误的发生。 为了解决ORA-01555错误,可以考虑以下几个方案: 1. 增加Rollback段的大小:可以通过增大回滚段的大小来解决ORA-01555错误。通过增加回滚段的大小,可以延长数据被重用的时间,从而减少ORA-01555错误的发生。 2. 设置合适的UNDO_RETENTION参数:可以通过设置UNDO_RETENTION参数来控制回滚段中数据的保留时间。增加UNDO_RETENTION的值可以延长数据被重用的时间,减少ORA-01555错误的发生。 3. 调整事务隔离级别:可以尝试调整事务的隔离级别,例如将隔离级别改为READ_COMMITTED,可以降低ORA-01555错误的发生概率。 此外,还可以根据具体情况进行其他的优化措施,例如优化SQL语句、调整并发事务的执行顺序等,以减少ORA-01555错误的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值