关于undo和consistent read

4 28th, 2009 | Posted by jacky | Filed under 大话技术

上周,同事作了一个关于undo internal的技术分享,发现我对这些技术细节都忘得七七八八了,这也证明我当初并没有真正理解其中的原理,今天又重温了一下,发现还是有一些问题没有想清楚。

这里我尽量用简单的语言描述其实现原理,内容涉及到itl,undo,cleanout,consistent read,ORA-1555等内容。

1.一致读产生的一般性原理:

构造一致读的过程实际上是一个递归的过程,用data block+undo构造出一个CR block,如果发现这个CR block还不够旧,就继续用这个CR block+undo来构造,直到构造出的小于query scn的CR block或者报1555错误。data block如何找到相应的undo,就要用到ITL,因为在构造CR block的过程中,不仅仅回滚了data block中的数据,ITL也同时回滚了(因为在undo entries中不仅仅包含数据的before image,也包括ITL的before image),这样不管要构造多少次,只要UNDO信息没有被覆盖掉,都可以通过block上的ITL找到相应的undo。

2.undo segment header上的control SCN

这个SCN是这个undo segment中的任意一个slot被覆盖时,这个slot的上一个事务的提交scn,就是这个undo segment可以回滚的最小SCN,如果查询的scn小于control scn,那么Oracle将直接返回1555,因为回滚也必然是失败的。这个control SCN的另外一个重要用途是,在delay cleanout时,如果对应的slot被覆盖,则用这个control SCN作为upper bound SCN作为事务的commit SCN,因为用这个SCN是安全的。

3.undo entries chain

我们把undo block中具体的undo信息称为undo entries,由于一个事务可能包含很多操作,在回滚时必须从最后一个entries向前回滚。首先我们通过undo segment header上的事务表找到undo block的地址,在这个undo block中记录了最后一个undo entries的位置(偏移量),每个undo entries中又记录了上一个的地址,这样就形成了一个undo entries chain。

4.undo segment header

回滚段头的主要结构是事务表,事务号是由undo segment number+slot number+sequence组成,当slot重用时,sequence number会增加一,用来唯一的标识一个事务。通过事务表可以找到最后一个undo entries所在的undo block。

我这里有几个疑问:

1.从一些资料上看到undo segment header上有一致性读,什么情况下undo segment header上需要一致性读?作用是什么?

2.在我的测试中,就算slot被重用,但是undo entries是不会被覆盖的。但是当slot被覆盖后,进入这些undo entries的入口没有了,这些undo entries会在什么情况下被使用?难道是flashback?

3.data block中的ITL中不仅记录了undo block的地址,还记录了undo entries的位置。是否可以通过undo segment header中的事务表就直接找到相应的undo记录吗?因为有可能slot已经被覆盖,通过事务表无法找到undo entries的入口。

–EOF–

标签:
  1. 木匠Charlie
    4 29th, 200902:43

    我咋越看越糊涂. 关于第二条,什么是control scn?

  2. jacky
    4 29th, 200909:18

    control scn是在undo segment header上的一个控制结构,你可以dump出来看一下。

  3. hoterran
    4 30th, 200919:08

    undo block entries 里是有itl 信息,就是用来找前一个undo block 用的,这个05大师的一个帖子里就有讲到。

    1 我觉得undo header 不需要一致性读了

    2 undo slot 和itl都被覆盖,貌似就切断了block 与undo block的所有联系,怀疑不能flashback 回来

    3 flashbback 就是通过slot,entries 找到已经提交的记录

    有错请鄙视~~~

  4. fcp
    4 30th, 200921:25

    1.从一些资料上看到undo segment header上有一致性读,什么情况下undo segment header上需要一致性读?

    这个问题,undo segment header 本身也有 undo信息存在,什么时候需要一致读呢,当根据itl中的信息去到 undo header 中发现transaction slot被覆盖了,那么可以根据undo信息重构 undo header cr block 。
    undo block 本身的变化不再产生undo,但是 undo header变化要产生undo。

  5. askwan
    5 1st, 200911:09

    暂时还看不太懂这些 希望以后能看懂啊 要努力啦

  6. jacky
    5 4th, 200910:33

    To fcp:你说的这个情况我考虑过,但是我没有发现其他的文档上有提及这部分内容,也没有通过实验得到印证。

  7. fcp
    5 4th, 200911:50

    要设计实验也是可以个,2k block的一个回滚段,事务表就会比较少,但回滚段很大。 这样给予回滚段头迅速被覆盖的机会。

    如果回滚段头事务槽的使用始终是循环的那更简单了,因为几千个提交就足够把回滚段循环覆盖个遍。

    若期望从文字中发现, ixora.com.au 里面肯定有的。

  8. 八神
    5 6th, 200920:59