有时候我们在执行select操作的时候也可能会产生redo,其一个可能原因就是oracle块清除。
在进行块清除的时候,如果是一个大事务,就会进行延迟块清除
块清除就是删除所修改数据块上与"锁定"有关的信息,即事务信息
Oracle在事务相关的提交列表中,记录下已修改的块列表,每个列表记录20个块,根据需要可能分配有多个这种列表.
这种块列表有一个上限,就是缓冲区缓存大小的10%.
如果一次修改的块,没有超过了缓冲区缓存大小的10%,并且这些块在内存中,则commit时,会清除块上的事务信息,
否则,就不会理会它,直到下次访问这些块时,再清除块中的事务信息,这就是延迟块清除.
因为这个Select修改了块的事务信息,所以就会产生Redo.
下面是根据ITPUB上的资料和我的理解整理的关于块清除时SCN的填写,以及什么情况产生"快照太旧"的错误.
延迟清除的块的下一个读者,首先根据块中的记录的回滚信息去查找回滚段中记录的commit时的SCN,
但回滚段可能已回绕,找不到提交时的scn了,
但是,从回滚段中可以得到一个最小的提交scn并且该事务已经提交肯定小于这个从回滚段中还存在的最小scn。
那么oracle给这个块清除的事务分配一个从回滚段中找到的最小事务scn。
这虽然不准确,但是是安全的,对于数据访问也不构成影响。所以叫 upper bound ,猜测的一个scn的上限。
延迟清除的块在被select 时,如果读的select 的scn 比这个回滚段里面最小的scn 还要小的话(回滚段已回绕),那么在回滚段里面找不到数
据了,oracle 就没有办法判断select 的SCN 与被要清除的数据块的大小关系,于是ora-01555就出现了,这个时候oracle 就不知道数据块里面
的数据是不是是查询时刻需要的数据.
如果select scn 大于回滚段里面最小的scn 的话,那么oracle 就使用这个最小的scn 来做为这个事务的 scn 来更新块的itl ,从而完成块的清除.
|