关于undo和consistent read
上周,同事作了一个关于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–
我咋越看越糊涂. 关于第二条,什么是control scn?
control scn是在undo segment header上的一个控制结构,你可以dump出来看一下。
undo block entries 里是有itl 信息,就是用来找前一个undo block 用的,这个05大师的一个帖子里就有讲到。
1 我觉得undo header 不需要一致性读了
2 undo slot 和itl都被覆盖,貌似就切断了block 与undo block的所有联系,怀疑不能flashback 回来
3 flashbback 就是通过slot,entries 找到已经提交的记录
有错请鄙视~~~
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。
暂时还看不太懂这些 希望以后能看懂啊 要努力啦
To fcp:你说的这个情况我考虑过,但是我没有发现其他的文档上有提及这部分内容,也没有通过实验得到印证。
要设计实验也是可以个,2k block的一个回滚段,事务表就会比较少,但回滚段很大。 这样给予回滚段头迅速被覆盖的机会。
如果回滚段头事务槽的使用始终是循环的那更简单了,因为几千个提交就足够把回滚段循环覆盖个遍。
若期望从文字中发现, ixora.com.au 里面肯定有的。
http://www.ixora.com.au/q+a/cr.htm#end