ITPub博客

首页 > 数据库 > Oracle > ORA-01555错误分析

ORA-01555错误分析

原创 Oracle 作者:Root__Liu 时间:2019-02-20 00:08:05 0 删除 编辑

最近在客户数据库会遇到ORA-1555的报错,分析了一下产生的原因以及如何规避它。

1、回滚段数据被覆盖

        原因:

        当进行DML操作时,undo段会记录数据变更前的状态(通过构造原数据的一致性数据块)。如果用户还没有进行commit操作,其他人查询此条数据会看到数据变更前的状态。因为其他用户读到的数据是undo段中原数据块中的数据,保证没有commit的数据读取的一致性。    

       会话A在9:50分的时候对T表发起了一次查询,需要10分钟完成查询结果打印。会话B在9:51分对T表进行了一次update,并且commit。此时undo段会记录会话B在update的反向操作,假设名为undo1。会话C在9:52分对T表进行了一次insert,并且同样commit。此时undo段会记录insert反向操作,假设名为undo2。会话A的查询在发起时已经记录数据库当前的SCN号,假设此时SCN号为950。由于ILT事务槽记录最新的SCN号,所以再与数据块头部ILT事务槽中的SCN号进行比对时发现当前SCN大于950,所以需要对undo段进行查询。查询到undo2段信息进行比对发现SCN大于950,通过undo中记录的事务信息在进行前一个数据变更查找,此时undo1的SCN还是大于950,再继续查找前面的undo信息,发现undo0的SCN号比950要早,此时会将undo0记录的数据的信息+未变更的数据块信息打印给用户。由于undo段是通过覆盖的方式进行记录的,如果时间过长或频繁进行DML操作。那么在寻找过程中可能会出现没有小于SCN号950的undo段,会返回一个经典错误ORA-1555 snapshoot too old(快照过旧),这样是为了避免幻影读、脏读等现象,保证读一致性的绝对特性。

        简单讲,就是SQL语句执行时间太长、UNDO表空间过小、事务量过大,提交过于频繁,导致执行SQL过程中进行一致性读时,修改的原数据(UNDO数据)在UNDO表空间中已经被覆盖,不能构造一致性读块。

        规避:

        1、加大回滚段的容量

         2、将undo_retention参数内的提交后保留时间设置更大一些

2、块延迟清除

        如果当一个查询触发延迟块清除的时候,ORACLE需要去查询回滚段获得该事务提交的SCN,如果事务前镜像信息已经被覆盖,并且查询的SCN小于回滚段记录中记录的最小提交SCN信息,那么oracle将无法判断查询的scn和事物提交scn的大小.则将commit 标记为 回滚段中所能找到的最小 scn(对于查询安全)。

        如果最近一次变更与查询间隔时间过长、间隔中进行过大量事务变更或频繁进行事务提交,造成undo段中的数据已经被覆盖,无法判断数据的变更情况和提交时间。此时oracle会查将该数据块中ITL事务信息清除并将commit SCN变更为回滚段中最老的事务,即最小的SCN号。以便保证数据能够查询,此时会报ORA-1555错误。



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

请登录后发表评论 登录
全部评论

注册时间:2018-08-08

  • 博文量
    22
  • 访问量
    44349