ITPub博客

首页 > Linux操作系统 > Linux操作系统 > consistent read(读一致性)的通俗理解(转)

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

原创 Linux操作系统 作者:wangkxxe 时间:2009-06-26 14:15:59 0 删除 编辑
首先介绍undo 中的简单结构:
undo header-->transaction table-->undo entries(undo block)-->
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---------------------------------------->>>>>>  这里有一个指针指向前一个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------------------------------------------>>>>>>这里的dba因为rci决定了它不是这个block的最
后一个record。
这是因为,如果你查询的表有很多个交易在修改,那也需要读取这些所有的这些交易所涉及的undo block,应用到重做
b):如果包含一个ITL纪录,存储这个ITL record到数据块(cr block),然后返回第四步。
这里比较迷惑,为什么一个undo entries上还会包含一个ITL纪录呢?哪里来的?

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

请登录后发表评论 登录
全部评论

注册时间:2009-02-25

  • 博文量
    68
  • 访问量
    93876