|
最初由 超级野人 发布
[B]不解?!! [/B]
呵呵,其实很简单,除了整个事务的undo record可以串起来,单个data block对应的undo record还有另外一条链子串起来的
还是用实验说话
[php]
SQL> drop table test;
表已删除。
SQL> create table test(i int,name char(1500));
表已创建。
SQL> insert into test values(1,'a');
已创建 1 行。
SQL> insert into test values(2,'b');
已创建 1 行。
SQL> insert into test values(3,'c');
已创建 1 行。
SQL> insert into test values(4,'d');
已创建 1 行。
SQL> insert into test values(5,'e');
已创建 1 行。
SQL> insert into test values(6,'f');
已创建 1 行。
SQL> insert into test values(7,'g');
已创建 1 行。
SQL> insert into test values(8,'h');
已创建 1 行。
SQL> insert into test values(9,'i');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select i,dbms_rowid.rowid_relative_fno(rowid) fno,
2 dbms_rowid.rowid_block_number(rowid) block# from test;
I FNO BLOCK#
---------- ---------- ----------
1 4 2460
2 4 2460
3 4 2460
4 4 2460
5 4 2461
6 4 2461
7 4 2461
8 4 2461
9 4 2462
已选择9行。
1. 首先更新block2460的一条数据
SQL> update test set name='aa' where i=1;
已更新 1 行。
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
10 23 323 2 161 317 43
看看block2460的ITL:
SQL> alter system dump datafile 4 block 2460;
系统已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.019.00000141 0x00000000.0000.00 C--- 0 scn 0x0000.000c83e9
0x02 0x000a.017.00000143 0x008000a1.013d.2b ---- 1 fsc 0x0000.00000000
对应的undo:
SQL> alter system dump datafile 2 block 161;
系统已更改。
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x2b irb: 0x2b icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f40 0x02 0x1e98 0x03 0x1e30 0x04 0x1d88 0x05 0x1d10
0x06 0x1ca8 0x07 0x1c00 0x08 0x1b98 0x09 0x1af0 0x0a 0x1a88
0x0b 0x19e0 0x0c 0x1978 0x0d 0x18d0 0x0e 0x1868 0x0f 0x17c4
0x10 0x171c 0x11 0x16b4 0x12 0x1610 0x13 0x158c 0x14 0x1528
0x15 0x1484 0x16 0x141c 0x17 0x139c 0x18 0x133c 0x19 0x12dc
0x1a 0x127c 0x1b 0x11a8 0x1c 0x1144 0x1d 0x10d8 0x1e 0x1098
0x1f 0x1044 0x20 0x0fd8 0x21 0x0f30 0x22 0x0e88 0x23 0x0de0
0x24 0x0d3c 0x25 0x0c94 0x26 0x0bf0 0x27 0x0b4c 0x28 0x0acc
0x29 0x0a70 0x2a 0x09cc 0x2b 0x0358
对应的undo record为0x26:
*-----------------------------
* Rec #0x2b slt: 0x17 objn: 10709(0x000029d5) objd: 10710 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x008000a1.013d.2a ctl max scn: 0x0000.000c7e58 prv tx scn: 0x0000.000c7e61
txn start scn: scn: 0x0000.00000000 logon user: 27
prev brb: 8388767 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
Array Update of 1 rows:
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 7
ncol: 2 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100099c hdba: 0x0100099b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [1500]
61 20 20 ......
注意这里的 op: Z
2. 再更新block2461的一条记录
SQL> update test set name='ee' where i=5;
已更新 1 行。
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
10 23 323 2 162 317 1
看看block2461的ITL:
SQL> alter system dump datafile 4 block 2461;
系统已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.019.00000141 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0x000a.017.00000143 0x008000a2.013d.01 ---- 1 fsc 0x0000.00000000
对应的undo:
SQL> alter system dump datafile 2 block 162;
系统已更改。
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x1 irb: 0x1 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x19a4
这里使用了新的undo block,应该是恰好上一个undo block满了:
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x1 irb: 0x1 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x19a4
*-----------------------------
* Rec #0x1 slt: 0x17 objn: 10709(0x000029d5) objd: 10710 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x008000a1
*-----------------------------
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
Array Update of 1 rows:
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 0
ncol: 2 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100099d hdba: 0x0100099b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [1500]
65 20 20 ......
注意这里的 op: Z
3. 继续更新block2460的一条记录:
SQL> update test set name='bb' where i=2;
已更新 1 行。
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
10 23 323 2 162 317 2
SQL> alter system dump datafile 4 block 2460;
系统已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.019.00000141 0x00000000.0000.00 C--- 0 scn 0x0000.000c83e9
0x02 0x000a.017.00000143 0x008000a2.013d.02 ---- 2 fsc 0x0000.00000000
SQL> alter system dump datafile 2 block 162;
系统已更改。
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x2 irb: 0x2 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x19a4 0x02 0x1358
*-----------------------------
* Rec #0x2 slt: 0x17 objn: 10709(0x000029d5) objd: 10710 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x01
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x008000a1.013d.2b
Array Update of 1 rows:
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 0
ncol: 2 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100099c hdba: 0x0100099b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [1500]
62 20 20 ......
注意到这里op: C uba: 0x008000a1.013d.2b这里指向了上一个undo block的一条undo record,正是block2460更新的第一条记录对应的undo
4. 继续更新block2461的一条记录:
SQL> update test set name='ff' where i=6;
已更新 1 行。
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
10 23 323 2 162 317 3
SQL> alter system dump datafile 4 block 2461;
系统已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.019.00000141 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0x000a.017.00000143 0x008000a2.013d.03 ---- 2 fsc 0x0000.00000000
SQL> alter system dump datafile 2 block 162;
系统已更改。
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x3 irb: 0x3 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x19a4 0x02 0x1358 0x03 0x0d0c
*-----------------------------
* Rec #0x3 slt: 0x17 objn: 10709(0x000029d5) objd: 10710 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x02
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x008000a2.013d.01
Array Update of 1 rows:
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 0
ncol: 2 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100099d hdba: 0x0100099b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [1500]
66 20 20 ......
注意到这里op: C uba: 0x008000a2.013d.01指向的是block2461更新的第一条记录对应的undo record。
5. 继续更新block2460的一条记录:
SQL> update test set name='cc' where i=3;
已更新 1 行。
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
10 23 323 2 162 317 4
SQL> alter system dump datafile 4 block 2460;
系统已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.019.00000141 0x00000000.0000.00 C--- 0 scn 0x0000.000c83e9
0x02 0x000a.017.00000143 0x008000a2.013d.04 ---- 3 fsc 0x0000.00000000
SQL> alter system dump datafile 2 block 162;
系统已更改。
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x4 irb: 0x4 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x19a4 0x02 0x1358 0x03 0x0d0c 0x04 0x06c0
*-----------------------------
* Rec #0x4 slt: 0x17 objn: 10709(0x000029d5) objd: 10710 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x03
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x008000a2.013d.02
Array Update of 1 rows:
tabn: 0 slot: 2(0x2) flag: 0x2c lock: 0 ckix: 0
ncol: 2 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100099c hdba: 0x0100099b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [1500]
63 20 20 ......
注意到这里op: C uba: 0x008000a2.013d.02指向的是block2460更新的第二条记录对应的undo record
6. 继续更新block2461的一条记录:
SQL> update test set name='gg' where i=7;
已更新 1 行。
SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
10 23 323 2 162 317 5
SQL> alter system dump datafile 4 block 2461;
系统已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.019.00000141 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0x000a.017.00000143 0x008000a2.013d.05 ---- 3 fsc 0x0000.00000000
SQL> alter system dump datafile 2 block 162;
UNDO BLK:
xid: 0x000a.017.00000143 seq: 0x13d cnt: 0x5 irb: 0x5 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x19a4 0x02 0x1358 0x03 0x0d0c 0x04 0x06c0 0x05 0x0074
*-----------------------------
* Rec #0x5 slt: 0x17 objn: 10709(0x000029d5) objd: 10710 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x04
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x008000a2.013d.03
Array Update of 1 rows:
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 2 ckix: 0
ncol: 2 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100099d hdba: 0x0100099b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [1500]
67 20 20 ......
注意到这里op: C uba: 0x008000a2.013d.03指向的是block2461更新的第二条记录
试验到这里,我们已经可以看到一个规律了,那就是:
1.事务的所有undo record,可以根据前面实验指出的rci和rdba全部串起来
2.每一个block中所有dml操作的记录对应的undo record可以通过op: C uba: xxxxxxx串起来
如果回滚整个事务,根据数据字典中记录得到事务最后一条undo record,可以获得整个事务的undo
如果一致性读取某个block,则可以根据该block中的ITL记录找到该block最后一条dml操作的记录
对应的undo record,通过op: C uba: xxxxxxx找到这个block对应的所有的undo record,这样,
最坏情况下,最多只需要扫描该block中被修改过的记录个数的undo block就可以构造出一致性块,
而不是楼主说的需要读取整个事务修改过的记录个数的undo block
--
[/php] |
|