oracle redo与undo_笔记10:延迟的块清除
延迟的块清除
块清除是导致ORA-01555错误的一个原因,尽管很难完全杜绝,不过好在毕竟并不多见,因为可能出现块清除的情况不常发生(至少在Oracle8i及以上版中是这样)。
总结:在块清除过程中,如果一个块已被修改,下一个会话访问这个块时,可能必须查看最后一个修改这个块的事务是否还是活动的。一旦确定该事务不再活动,就会完成块清除,这样另一个会话访问这个块时就不必再历经同样的过程。要完成块清除,Oracle会从块首部确定前一个事务所用的undo段,然后确定从undo首部能不能看出这个块是否已经提交。可以用以下两种方式完成这种确认。一种方式是Oracle可以确定这个事务很久以前就已经提交,它在undo段事务表中的事务槽已经被覆盖。另一种情况是COMMIT SCN还在undo段的事务表中,这说明该事务只是稍早前刚提交,其事务槽尚未被覆盖。
要从一个延迟的块清除收到ORA-01555错误,以下条件都必须满足。
.首先做了一个修改并COMMIT,块没有自动清理(即没有自动完成“提交清除”,例如事务修改了太多的块,在SGA块缓冲区缓存的确10%中放不下)。
.其他会话没有接触这些块,而且在我们这个“倒霉”的查询(稍后显示)命中这些块之前,任何会话都不会接触它们。
.开始一个长时间运行的查询。这个查询最后会读其中的一些块。这个查询从SCN+1开始,这就是读一致SCN,必须将数据回滚到这一点来得到读一致性。开始查询时,上述修改事务的事务条目还在undo段的事务表中。
.查询期间,系统中执行了多个提交。这些事务没有接触这些已修改的块(如果确实接触到,也就不存在问题了,因为它们会清理旧事务,解决清理问题)。
.由于出现了大量的COMMIT,undo段中的事务表要回绕并重用事务槽。最重要的是,将循环地重用原来修改事务的事务条目。另外,系统重用了undo段的区段,以避免对undo段首部块本身的一致读。
.此外,由于提交太多,undo段中记录的最低SCN现在超过了t1(高于查询的读一致SCN)如果查询到达某个块,而这个块在查询开始之前已经修改并提交,就会遇到麻烦。正常情况下,会回到块所指的undo段,找到修改了这个块的事务的状态(换句话说,它会找到该事务的COMMIT SCN)如果这个COMMIT SCN小于t1,查询就可以使用这个块。如果该事务的COMMIT SCN大于t1,查询就必须回滚这个块。不过,问题是,在这种特殊的情况下,查询无法确定块的COMMIT SCN是大于还是小于t1。相应地,不清楚查询能否使用这个块映像。这就导致了ORA-01555错误。
万一你发现遭遇了这个问题,即选择SELECT一个表时(没有应用其他DML操作)出现了ORA-01555错误,可以试试以下解决方案。
.首先,保证使用的事务“大小适当”。确保没有不必要地过于频繁地提交。
.使用DBMS_STATS扫描相关的对象,加载之后完成这些对象的清理。由于块清除是极大量的UDPATE或INSERT造成的,所以很有必要这样做。
.允许undo表空间扩大,为之留出扩展的空间,并增加undo保持时间。这样在长时间运行查询期间,undo段事务表中的事务槽被覆盖的可能性就会降低。针对导致ORA-01555错误的另一个原因(undo段太小),也同样可以采用这个解决方案。
.减少查询的运行时间,即调优。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5272.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
