老师,请教关于延迟块清除导致的01555错误!

本帖最后由 xychong123 于 2011-4-9 23:29 编辑

1,一个事务更新了该数据块,但在提交前,我们手工将 buffer cache 中的数据做了
flush,再做提交。这时的数据块上只记录了锁标志,没有事务标志和Commit SCN。


SQL> update t_multiver set b=115 where a=1;   
SQL> alter system flush buffer_cache;
SQL> commit;

2,
进行非常多的事务,将回滚段中的事务信息表中的数据全部覆盖:
SQL> begin
  2    -- overwrite rollback slot
  3    for i in 1..40000 loop
  4      update t_dual set dummy=1;
  5      commit;
  6    end loop;   7  end;
  8  /



3,
开始读取表。
SQL> var cc refcursor
SQL>
SQL> begin
  2  open :cc for select * from t_multiver;
  3  end;
  4  /



SQL> print :cc
ERROR:
ORA-01555: snapshot too old: rollback segment number 20 with name
"_SYSSMU20$"
too small
no rows selected   <------为什么没数据返回,数据丢失了?


老师,我的疑问就是,我在前面已经做了commit,所以数据就应该能过保存在表里面!可是这是我在selct的时候却,不能够查找到数据,那我在那时刻所作的操作产生的数据就因为undo问题,数据就丢失了


oracle中已经commit的数据难道也丢失?
标签: 暂无标签
xychong123

写了 5 篇文章,拥有财富 59,被 3 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

P4 | 发表于 2012-7-12 17:13:54
没人回,还是自己给自己一个答案了

延迟清除的块的下一个读者,首先根据块中的记录的回滚信息去查找回滚段中记录的commit时的SCN,如果能找到,那么正常清除,会产生redo log,这也是select会产生redo的原因。
但回滚段可能已回绕,找不到提交时的scn了,
但是,从回滚段事务slot中可以得到一个最小的提交scn并且需要清理的事务已经提交肯定小于这个从回滚段中还存在的最小scn,这是因为事务slot是循环使用的,既然已经回绕,那说明当前slot中最小SCN大于需要清理的事务的SCN。
对于回滚段已回绕的情况,即transaction slot中的最小提交SCN大于待清理事务的SCN,有以下两种可能:
如果select 时的scn 大于回滚段事务slot中最小的scn, 也即select时间点在需要清理的事务提交之后,oracle会给这个块清除的事务分配一个从回滚段中找到的最小事务scn,从而完成块的清除.。这虽然不准确,但是是安全的,对于数据访问也不构成影响。所以叫 upper bound ,猜测的一个scn的上限。
如果select 的scn 比这个回滚段事务slot里面最小的scn 还要小的话,那么oracle需要构造select那个scn的一致块,如果回滚段事务slot已回绕,在回滚段里面找不到数据了,oracle 无法构造一致性块,于是ora-01555就出现了,这个时候oracle 就不知道数据块里面的数据是不是是查询时刻需要的数据.

评分

参与人数 1金币 +10 收起 理由
iidba + 10 分享精神和责任心

查看全部评分

回复

使用道具

管理员 | 发表于 2012-7-12 17:25:47
一年前的帖子了,当时老相应该比较忙,标注了“老师”其他人又不敢接{:soso_e113:},帖子就沉了。

楼主的责任心真的很值得大家学习,自己得到提高的时候也不忘分享给大家,非常值得赞扬。
回复

使用道具

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈