consistent read(读一致性)的通俗理解

首先介绍undo 中的简单结构:
undo header--&gttransaction table--&gtundo entries(undo block)--&gt
undo entries包含的只有一个行改变的col值的undo,并不包含整个行的befor image。
KDO undo record:
KTB Redo op: 0x02 ver: 0x01 op: C uba: 0x02000004.0005.0a
KDO Op code: URP xtype: XA bdba: 0x01c00007 hdba: 0x01c00006
itli: 1 ispac: 0 maxfr: 4863 tabn: 0 slot: 1(0x1) flag: 0x2c
lock: 0 ckix: 0 ncol: 8 nnew: 2 size: -1
col 5: [ 3] c2 20 24
col 7: [ 2] c1 1f 





consistent read:
1.读取数据块,如果该块在内存中,则增加一个克隆用于undo
2.读取行头:
tab 0, row 0, @0x1e4c
tl: 44 fb: --H-FL-- lb: 0x1 cc: 8
3.检查lb是否这里有一个itl:
Itl Xid Uba Flag
0x01 xid: 0x0003.000.00000010 uba: 0x02000004.0005.09 ----
4.如果有,则读取这个itl的xid,xid=us#.slot#.wrap#

5.读取交易表,如果这个交易已经提交(state=9表示提交)并且有了一scn小于当前查询的system change number,
那么clean out这个块,继续下一个块(如果需要的话)并且返回第一步。(在每一个查询的时候都将产生一个查询
scn,在该scn一下的commit scn都认为对应的交易已经提交)
TRN TBL:
index state cflags wrap# uel scn dba nub
--------------------------------------------------------------------------
0x00 10 0xc0 0x0010 0x0000 0x0000.00075fec 0x02000004 0x00000001
0x01 9 0x00 0x000f 0x0002 0x0000.00075f77 0x00000000 0x00000000
6.如果没有提交,那么读取最新改变的undo block根据transaction table中显示的dba(该地址为undo entries中最
新改变的块)
7.对比这个块的交易号同交易表中的交易号。如果在undo block中的交易号不等于交易表中的交易号,那么报告错误:
ORA-01555 “Snapshot Too Old.”.
xid: 0x0001.01d.000023a4 seq: 0x2a7 cnt: 0x3f irb: 0x3f icl: 0x0 flg: 0x0000

Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f68 0x02 0x1ee8 0x03 0x1e68 0x04 0x1de8 0x05 0x1d68
0x06 0x1cec 0x07 0x1c6c 0x08 0x1bec 0x09 0x1b6c 0x0a 0x1aec
0x0b 0x1a6c 0x0c 0x19f0 0x0d 0x1970 0x0e 0x18f0 0x0f 0x1874
0x10 0x17f8 0x11 0x1778 0x12 0x16f8 0x13 0x1678 0x14 0x15f8
8.如果这个块的交易号等于交易表中的交易号,那么从这个undo entry的头开始,应用改变到块上(该块为在内存中
克隆的块)
If the Transaction IDs are identical, make a copy of the data block in memory.
Starting with the head undo entry, apply the changes to the copied data block.
9.如果这个undo enties的尾巴上有其他的块地址(因为一个交易可能占用了好几个undo块),那么将这个undo block
读到内存中重复分析第七步和第八步。重复7和8步直到首先的record不在包含其他块的地址。
10.当这里不再有前一个数据块的地址,那么这个交易就完全被undo了。(因为undo 块是从最后一个块往前读的,这
是为了保证在你读的时候,最新改变的数据都能在undo中体现)
11.如果这个undo entry包含:
a):包含一个指向前一个交易undo block的地址,读取这个交易的id号在这个前一个交易的undo block头里并读取相应
的交易表entries,返回第五步。record纪录也是从后往前读的,因此有irb指定先读取哪一个。
* Rec #0x1 slt: 0x00 objn: 48636(0x0000bdfc) objd: 49636 tblspc: 33(0x00000021)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00801b7c----------------------------------------&gt>>>>> 这里有一个指针指向前一个undo block证明
这个undo chain上还有一些undo 块。
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x00801b7c.02a7.3e
KDO Op code: URP row dependencies Disabled
xtype: XA bdba: 0x054016c1 hdba: 0x054016b9
itli: 1 ispac: 0 maxfr: 4863
tabn: 0 slot: 85(0x55) flag: 0x2c lock: 0 ckix: 0
ncol: 8 nnew: 5 size: 0
col 3: [ 3] c1 06 36
col 4: [ 3] c1 06 36
col 5: [ 1] 30
col 6: [ 2] c1 02
col 7: [ 6] c4 02 23 38 39 3d

*-----------------------------
* Rec #0x2 slt: 0x00 objn: 48636(0x0000bdfc) objd: 49636 tblspc: 33(0x00000021)
* Layer: 11 (Row) opc: 1 rci 0x01
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000------------------------------------------&gt>>>>>这里的dba因为rci决定了它不是这个block的最
后一个record。
这是因为,如果你查询的表有很多个交易在修改,那也需要读取这些所有的这些交易所涉及的undo block,应用到重做
b):如果包含一个ITL纪录,存储这个ITL record到数据块(cr block),然后返回第四步。
这里比较迷惑,为什么一个undo entries上还会包含一个ITL纪录呢?哪里来的?

----------------------

一句话: 一致读就是session查询所读到的数据,是查询开始的时间点之前已经提交的数据+当时session自己做出变更还没有提交的数据。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-84326/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/35489/viewspace-84326/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值