ORA-01555: snapshot too old: rollback segment number 问题剖析上

一直打算对这个常见错误进行整理的,正好今天宁哥催了一下。随便重新理解这个问题,这个问题打算从三个方面进行分析,分别为问题剖析,实验重现,解决策略。
要想了解这个告警错误,就必须从原理上进行剖析,所以先对该错误的发生原理进行剖析下。
 
   在平常的数据库运维工作中,会经常看到各种ORA-01555错误类型,有时候是由于回滚段太小,有时候是查询时长,但也有其他的原因。利用oracle官方文档的解释(10630.1),和网上一些大牛的解决思路,我整理分析了一下,汇总为一个比较完整的总结。解决ORA-01555问题前,我们需要了解一些Oracle的内部机制,首先简单解释一下一致读和延迟块清除(read consistency and block cleanouts).

 1.一致性读情况
    和前文一样,任何看似比较难的问题,仔细理解下来就会回到一个很简单的知识点,如果读过Oracle的 concepts手册应该会比较了解,没读过也没关系。
 这里有个概念就是“脏读”,Oracle数据库时绝对不允许脏读的,什么是脏读?当一个事务读取了另一个事务中未提交的数据时,会发生脏读。举个例子,假设一个事务更新了某个列的值,但是没有提交,第二个事务读取已经更新的值(脏读)。第一个事务回滚了事务,是的该事务读取的依然是原来的值,但是第二个事务继续使用更新的值,这会破坏数据的完整性。
Oracle使用回滚段重建数据的一致读快照,每当事务进行任何修改时,快照记录和复制到回滚段和数据块头的变化和回退的地址标记前,该数据块里面还保持着最好提交的SCN。 Oracle采用SCN(系统变更号)来标识特定的时间点,可以定义数据库中任何一个时间点的查询状态,保证数据的一致读。
如果一个数据块有其他的事务,或者数据以及最近SCN修改后没有提交,然后将从回滚段保存中的快照重建该数据。如果Oracle在快照长时间运行间,无法进行重建该查询,所以会产生ORA-01555错误。
按熊爷的说法是:
“SQL语句执行时间太长,或者UNDO表空间过小,或者事务量过大,或者过于频繁的提交,导致执行SQL过程中进行一致性读时,SQL执行后修改的前镜像(即UNDO数据)在UNDO表空间中已经被覆盖,不能构造一致性读块”

  2.延迟块清除
     这里举个例子, 假设有一个更新有百万行数据表的事务,很显然这会有大量的数据访问,当用户提交了事务,Oracle不再继续访问这些块,那么在下一次事务访问时,就会更新影响到,因此称为延迟块清除。每当Oracle改变了一个数据块(表,索引等),它会被存储在用于识别具有保存回滚信息更改的指针中。我们知道,Oracle在更新数据块时,会在回滚段中记录这一更新动作,并且会产生一个SCN,在回滚段中,会有对应的一个事务ID。在事务提交前,会在数据块头记录下这个SCN,事务ID,回滚地址,如前面说的指针中。并且会在事务列表中设置一个锁,用于记录这个事务在这个数据块中产生的锁的数目,同时在对应修改的数据记录上放以一个行级锁。当事务提交时,并不会全不清除,只是在事务列表中做上相应标记,告诉后面访问该数据块的事务,那些事务已经提交了,如果发现前面的事务没有提交,并要访问的数据块记录被锁住了,就会被阻塞。否则只有清除相应的锁标志,并提交自己的锁标志,循环该动作。这就叫做延迟块清除。

    而如果前面的事务在提交之前buffer cache中的脏数据已经被DBwn进程写回,那么在事务表中的事务标志就不会被更新,并且数据块的事务列表也不会记录下事务的Commit SCN。后面的事务或查询语句访问该数据块时,为了检测是否需要进行一致性读(如果数据块的事务列表中记录的提交事务的Commit SCN大于当前访问该数据块的SCN,则需要进行一致性读),就需要通过回滚段地址和事务ID到回滚段的事务信息表中去检查前面事务的状态和它的Commit SCN,确定是否做一致性读,最后将前面事务在该数据块上的标志做一次Cleanout。



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

转载于:http://blog.itpub.net/30430420/viewspace-1796453/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值