好多朋友都不知道ITL中的UBA(Undo Block Address)和KTUXE(Kernel Transaction Undo trans(X)action Entry)中的UBA有啥区别。其实这里的区别还是非常明显的:
ITL中的UBA表示这个ITL所在的block历经的最后一次改变所对应的undo record所在的UBA,用于一致读。
KTUXE中的UBA表示所对应的transaction的undo chain的最后一个UBA,用于transaction的回滚。
注意,ITL中的UBA和KTUXE中的UBA是完全可以不一致的!
我们来看一个不一致的实例:
SQL> create table t1(c1 varchar2(10),c2 char(2000),c3 char(2000),c4 char(2000));
Table created
SQL> insert into t1 values('cuihua1','1','1','1');
1 row inserted
SQL> insert into t1 values('cuihua2','2','2','2');
1 row inserted
SQL> commit;
Commit complete
SQL> update t1 set c2='1_1',c3='1_1',c4='1_1' where c1='cuihua1';
1 row updated
SQL> update t1 set c2='2_2',c3='2_2',c4='2_2' where c1='cuihua2';
1 row updated
SQL> commit;
Commit complete
SQL> alter system checkpoint;
System altered
SQL> select c1,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid) location from t1;
C1 LOCATION
---------- --------------------------------------------------------------------------------
cuihua1 116_44570
cuihua2 116_44571
BBED> set file 116 block 44570
FILE# 116
BLOCK# 44570
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0] @2168 0x2c
BBED> dump
File: /cadras01/oradata/astca/drastbs_19.dbf (116)
Block: 44570 Offsets: 2168 to 2679 Dba:0x1d00ae1a
------------------------------------------------------------------------
2c020407 63756968 756131fe 07d0315f 31202020 20202020 20202020 20202020
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
......省略显示部分内容
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
<32 bytes per line>
BBED> p ktbbh
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20 0x01 (KDDBTDATA)
union ktbbhsid, 4 bytes @24
ub4 ktbbhsg1 @24 0x000151a6
ub4 ktbbhod1 @24 0x000151a6
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 0x3858cf9a
ub2 kscnwrp @32 0x076d
b2 ktbbhict @36 2
......省略显示部分内容
struct ktbbhitl[1], 24 bytes @68
struct ktbitxid, 8 bytes @68
ub2 kxidusn @68 0x0007
ub2 kxidslt @70 0x0013
ub4 kxidsqn @72 0x0001861c
struct ktbituba, 8 bytes @76
ub4 kubadba @76 0x00800070
ub2 kubaseq @80 0x4175
ub1 kubarec @82 0x0d
ub2 ktbitflg @84 0x2001 (KTBFUPB)
union _ktbitun, 2 bytes @86
b2 _ktbitfsc @86 0
ub2 _ktbitwrp @86 0x0000
ub4 ktbitbas @88 0x3858cfb6
BBED> set file 116 block 44571
FILE# 116
BLOCK# 44571
BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0] @2168 0x2c
BBED> dump
File: /cadras01/oradata/astca/drastbs_19.dbf (116)
Block: 44571 Offsets: 2168 to 2679 Dba:0x1d00ae1b
------------------------------------------------------------------------
2c020407 63756968 756132fe 07d0325f 32202020 20202020 20202020 20202020
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
......省略显示部分内容
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
<32 bytes per line>
BBED> p ktbbh
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20 0x01 (KDDBTDATA)
union ktbbhsid, 4 bytes @24
ub4 ktbbhsg1 @24 0x000151a6
ub4 ktbbhod1 @24 0x000151a6
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 0x3858cfb1
ub2 kscnwrp @32 0x076d
b2 ktbbhict @36 2
......省略显示部分内容
struct ktbbhitl[1], 24 bytes @68
struct ktbitxid, 8 bytes @68
ub2 kxidusn @68 0x0007
ub2 kxidslt @70 0x0013
ub4 kxidsqn @72 0x0001861c
struct ktbituba, 8 bytes @76
ub4 kubadba @76 0x12c00051
ub2 kubaseq @80 0x4176
ub1 kubarec @82 0x01
ub2 ktbitflg @84 0x2001 (KTBFUPB)
union _ktbitun, 2 bytes @86
b2 _ktbitfsc @86 0
ub2 _ktbitwrp @86 0x0000
ub4 ktbitbas @88 0x3858cfb6
SQL_astca>alter system dump undo header '_SYSSMU7$';
System altered.
相应trace文件中的内容:
index state cflags wrap# uel scn dba parent-xid nub stmt_num
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x179d5 0x0013 0x076d.3858cec4 0x00800070 0x0000.000.00000000 0x00000001 0x00000000
......省略显示部分内容
0x13 9 0x00 0x1861c 0x0008 0x076d.3858cfb6 0x12c00051 0x0000.000.00000000 0x00000002 0x00000000
......省略显示部分内容
0x2f 9 0x00 0x18047 0x0004 0x076d.3858cdbf 0x0080006f 0x0000.000.00000000 0x00000001 0x00000000
从上述结果我们我们可以清晰的看到:
1、 当我起第二个transaction去更新t1里的两条记录的时候,很明显,t1所在的两条记录的block(即116_44570和116_44571)所对应的XID均为0007.0013.0001861c;
2、 0007.0013.0001861c所在的KTUXE中的UBA为0x12c00051
3、 116_44570所在的对应上述XID的ITL中的UBA为0x00800070,注意这里已经和上述KTUXE中的UBA不一致了!
4、 116_44571所在的对应上述XID的ITL中的UBA为0x12c00051,这里是和上述KTUXE中的UBA一致。
有兴趣的朋友可以自己动手dump一下相应的undo block,这对于深刻理解oracle中的redo和undo(undo block中会以redo中的change vector方式来存储undo record)机制是有莫大的好处的。