由于水平有限难免出现错误,全部观点仅代表作者观点
大家都知道在数据块的头部包含了一个事物层,其中包含了多个ITL。
我这里做了2次DELETE 一直不COMMIT 用于观察如下:
SQL> delete from testmyt where username='DIP';
1 row deleted
SQL> delete from testmyt where username='SCOTT';
1 row deleted
关于DUMP数据块和UNDO SEGMENT HEADER的语法如下:
alter system dump datafile 1 block 91361;
alter system dump undo header '_SYSSMU12_3031818529'; 其格式大致为如下: Itl Xid Uba Flag Lck Scn/Fsc 0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.001f83a8 0x02 0x000c.00a.00000014 0x00c000fc.0018.1e ---- 2 fsc 0x00e4.00000000 0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 所有讨论围绕 0x02 0x000c.00a.00000014 0x00c000fc.0018.1e ---- 2 fsc 0x00e4.00000000 展开 分别做下解释: 1、XID Identifier of the transaction owning the ITL, composed of three items: usn#.slot#.wrap# 这部分XID实际对应了V';
其格式大致为如下:
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.001f83a8
0x02 0x000c.00a.00000014 0x00c000fc.0018.1e ---- 2 fsc 0x00e4.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
所有讨论围绕
0x02 0x000c.00a.00000014 0x00c000fc.0018.1e ---- 2 fsc 0x00e4.00000000
展开
分别做下解释:
1、XID
Identifier of the transaction owning the ITL, composed of three items:
usn#.slot#.wrap#
这部分XID实际对应了VTRANSACTION中的
XIDUSN XIDSLOT XIDSQN
------- ---------- ----------
12 10 20
USN对应了dba_rollback_segs中的segment_id
xidsolt及事物表中的槽号可以查看
select * from xktuxe where ktuxeusn=12或者DUMP SEGMENT HEADR找到其槽号对应的信息如下 index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt ------------------------------------------------------------------------------------------------ ..... 0x0a 10 0x80 0x0014 0x0000 0x0000.001f83b0 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 0 ..... wrap#表示这个槽重用的多少次每次重用+1,(根据事物表的分析可以发现每次重用槽位的WRAP#必然是最小值同时commit scn最小值等会观察事物表的时候在进行分析) 我这里是从用的第20次,同样xktuxe where ktuxeusn=12或者DUMP SEGMENT HEADR找到其槽号对应的信息如下
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
.....
0x0a 10 0x80 0x0014 0x0000 0x0000.001f83b0 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 0
.....
wrap#表示这个槽重用的多少次每次重用+1,(根据事物表的分析可以发现每次重用槽位的WRAP#必然是最小值同时commit scn最小值等会观察事物表的时候在进行分析)
我这里是从用的第20次,同样xktuxe或者DUMP SEGMENT HEADR也能找到相应的信息。
2、Uba
Undo block address (UBA) of the record in the undo segment: DBA.seq#.rec#
这部分是对应了UNDO块的地址信息
DBA对应的是块的地址。
seq#对应的是这个块重用的次数,每次重用都会相应的增加,这个值和UNDO的重用机制有关,UNDO的重用必须选取小于新一轮SEQ值的块。
rec#最后一次使用到UNDO块中的位置,这个值会和事物表控制信息(ktuxc)中的KTUXCUBA形成对比这个值是事物的开始的位置。
3、Flag
事物状态值
—- = transaction is active, or committed pending cleanout
C— = transaction has been committed and locks cleaned out
-B– = this undo record contains the undo for this ITL entry
–U- = transaction committed (maybe long ago); SCN is an upper bound
—T = transaction was still active at block cleanout SCN
4、LCK
Number of locks held by the transaction in the block
应该理解为本事物导致了多少个行级锁,我这里一个事物同时更改了2条数据,所以是2
5、Scn/Fsc
If the transaction has been committed, the SCN of the transaction,If the
transaction has not been committed, the free space credits owned by this
transaction (if any)
可以看到这个值实际上是2个值,如果事物提交就是其COMMIT SCN,如果没有提交就是
快中空闲空间的位置。
关于这一部分我们来看2个ORACLE 给出的图解


接下来我们来看一下和ITL息息相关的UNDO SEGMENT HEADER的事物表(Transaction Table Header KTUXE)
以及事物表头(Transaction Table Header KTUXC)
TRN CTL:: seq: 0x0018 chd: 0x0007 ctl: 0x0021 inc: 0x00000000 nfb: 0x0000
mgc: 0xb000 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x00c000fc.0018.1d scn: 0x0000.001f74de
......
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x0014 0x0002 0x0000.001f805f 0x00c000fc 0x0000.000.00000000 0x00000002 0x00000000 1426827612
0x01 9 0x00 0x0014 0x0000 0x0000.001f8047 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426827611
0x02 9 0x00 0x0014 0x0003 0x0000.001f8091 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426827627
0x03 9 0x00 0x0014 0x0004 0x0000.001f8122 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426827926
0x04 9 0x00 0x0014 0x0005 0x0000.001f8204 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x05 9 0x00 0x0014 0x0008 0x0000.001f8210 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x06 9 0x00 0x0014 0x0021 0x0000.001f8240 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x07 9 0x00 0x0013 0x000b 0x0000.001f74ef 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
0x08 9 0x00 0x0014 0x001e 0x0000.001f821c 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x09 9 0x00 0x0014 0x0006 0x0000.001f8234 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x0a 10 0x80 0x0014 0x0000 0x0000.001f83b0 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 0
0x0b 9 0x00 0x0013 0x000e 0x0000.001f74fc 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
0x0c 9 0x00 0x0013 0x000f 0x0000.001f7516 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
0x0d 9 0x00 0x0013 0x001b 0x0000.001f7b87 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426824647
0x0e 9 0x00 0x0013 0x000c 0x0000.001f7509 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
0x0f 9 0x00 0x0013 0x0010 0x0000.001f7523 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
0x10 9 0x00 0x0013 0x0011 0x0000.001f7530 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
0x11 9 0x00 0x0013 0x0012 0x0000.001f76f2 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426821946
0x12 9 0x00 0x0013 0x0014 0x0000.001f77e0 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426822546
0x13 9 0x00 0x0013 0x0016 0x0000.001f7a4f 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426824047
0x14 9 0x00 0x0013 0x0015 0x0000.001f78d5 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426823202
0x15 9 0x00 0x0013 0x0013 0x0000.001f7a21 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426824045
0x16 9 0x00 0x0013 0x0017 0x0000.001f7a5b 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426824047
0x17 9 0x00 0x0013 0x0018 0x0000.001f7a67 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426824047
0x18 9 0x00 0x0013 0x0019 0x0000.001f7a73 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426824047
0x19 9 0x00 0x0013 0x001a 0x0000.001f7a7f 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426824047
0x1a 9 0x00 0x0013 0x000d 0x0000.001f7a9d 0x00c000fb 0x0000.000.00000000 0x00000002 0x00000000 1426824053
0x1b 9 0x00 0x0013 0x001c 0x0000.001f7c54 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426825247
0x1c 9 0x00 0x0013 0x001d 0x0000.001f7c61 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426825247
0x1d 9 0x00 0x0013 0x001f 0x0000.001f7cc3 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426825498
0x1e 9 0x00 0x0013 0x0009 0x0000.001f8228 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x1f 9 0x00 0x0013 0x0020 0x0000.001f7e8e 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426826447
0x20 9 0x00 0x0013 0x0001 0x0000.001f7f03 0x00c000fb 0x0000.000.00000000 0x00000001 0x00000000 1426826748
0x21 9 0x00 0x0013 0xffff 0x0000.001f826b 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828610
关于TRN CTL及事物表头(Transaction Table Header KTUXC)我们着重关注4个值
In the above slide, the important fields in protecting a given transaction are SCN,
UBA, CHD, and CTL.
For a transaction, a transaction slot is allocated during bind phase, which is at
transaction begin time. The CHD points to the next Tx slot to allocate. To preserve the
data within this Tx slot, the Tx commit SCN is saved in KTUXCSCN, the
KTUXCUBA field will identify the undo block to protect the changes to KTUXC,
and the CHD and CTL will be updated to reflect the next Tx slot to be reused, and the
latest committed slot within the transaction table respectively. These changes are
required to ensure rollback of the transaction, and read consistency of the Tx table
header.
The header of the Tx table (KTUXC) is modified:
? KTUXCSCN updated with the SCN of the reused slot
? KTUXCCHD points to the new oldest committed Tx
? KTUXCCTL points to the newest committed Tx
? KTUXCUBA points to the undo record created to protect the begin transaction
associated with the first change of the Tx
KTUXCHD就是下一次事物将使用的事物操,而他实际上是最老的记录的COMMIT的SCN的事物槽,我这里指向了chd: 0x0007,我们可以看一下他的完整信息
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x07 9 0x00 0x0013 0x000b 0x0000.001f74ef 0x00c000fa 0x0000.000.00000000 0x00000001 0x00000000 1426820746
可以看到他的SCN 实际上是0000.001f74ef,虽然这个值是16进制的但是很容易在整个事物表中发现他是整个事物表中COMMIT SCN最老的一个事物操
而他的WRAP#为13,所以下次从用的必然就是他
KTUXCTL表示的最新的COMMIT SCN 的事物槽的位置,我这里指向了ctl: 0x0021,其完整信息如下:
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x21 9 0x00 0x0013 0xffff 0x0000.001f826b 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828610
同样0x0000.001f826b是最新的COMMIT SCN,注意这里是COMMIT SCN 虽然0x0a行才是最新的但实际上他是ACTIVE 状态的,还没有COMMIT
KTUXCSCN表示最近一次从用事物表记录的COMMIT SCN,及被重用条目的COMMIT SCN,我这里是scn: 0x0000.001f74de,说明这个COMMIT SCN的
事物表条目被重用了,应该就是0x0a原有的COMMIT SCN
KTUXCUBA这个值代表了整个事物表中最老的一个事物的第一条更改的位置,我这里是uba: 0x00c000fc.0018.1d,当然我这里也只有一个事物,
这里和ITL中的0x00c000fc.0018.1e(这个值代表是最后一个更改所在的位置)有一定对比性但并不是总是如此,一个UNDO SEGMENT可能
包含很多TRANSACTION,当然一个事物会尽量使用一个UNDO SEGMENT,按照吕海波ORACLE内核揭秘一书中关于UNDO的描述当UNDO TBALESPACE
可用空间降低到50%左右的时候,一个UNDO SEGMENT会包含多个事物。
这样也就阐明了事物表条目重用的规则,他总是选取COMMIT SCN最老的值进行重用,重用后WRAP#增加1。
接下来我们看一下事物表(Transaction Table Header KTUXE)
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
......
0x09 9 0x00 0x0014 0x0006 0x0000.001f8234 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 1426828526
0x0a 10 0x80 0x0014 0x0000 0x0000.001f83b0 0x00c000fc 0x0000.000.00000000 0x00000001 0x00000000 0
......
这里截取两个条目就可以了,分别说明
INDEX:事物表槽号
STATE:条目状态 9是非活动 10代表活动
CFLAGS:标记位,0x00表示无实物,0x10死事物,0x80活动事物,0x90正在被回滚的死事物
WRAP#:如前所说是一个计数器
UEL:Used to store starting extent of an active transaction, or the next pointer in the
list of committed transactions if transaction inactive 这部分所谓的指针还不太清楚有
何用。还需要继续学习
scn:System commit number for prepare/commit ,对于提交的事物是COMMIT SCN,对已没有提交的事物是开始SCN,这里可以从VTRAINSACTION中得到证明对于这个事物我VTRANSACT的值是
START_TIME START_SCNB START_SCNW
-------------------- ---------- ----------
03/20/15 13:31:57 2065328 0
SQL> select to_number('1f83b0','xxxxxxxxxxx') from dual;
TO_NUMBER('1F83B0','XXXXXXXXXX
------------------------------
2065328
可以看到是能够对应上的。
dba:就是最后一个UNDO块所在的地址,这个值在ITL也有。
PTX (Par XID): Parent XID, for PDML
NUB:当前事物使用的UNDO块数
stmt_num:未知
cmt:记录一个COMMIT时间,从1970年1月1日以来的秒。
本块信息实际也可以通过XKTUXE进行查看 select indx,ktuxesta,ktuxecfl,ktuxesqn wrap#,ktuxescnw scnw,ktuxescnb scnb,ktuxerdbf dba_file,ktuxerdbb dba_block,ktuxesiz nub from xktuxe where ktuxeusn=12;
这里还要着重强调一下,本文中包含了2个计数器
一个是
usn#.slot#.wrap# 中的WRAP#也就是V$TRANSACTION中的XIDSQN
一个是
DBA.seq#.rec#中的seq#。
他们都是计数器但是作用范围不一样,一个是事物表条目中的计数器,一个是UNDO BLOCK中的计数器,他们和事物表条目或者UNDO BLOCK分配的机制相关,详细参见本文,这也是
长久以来迷惑广大DBA的地方,所以着重阐明。
最后吐槽一下学习内核的辛苦,每写一篇文章,需要翻阅大量的文档资料,并且不一定完全正确,而且会消耗大量的时间,但是我坚信这个过程是宝贵的,长期坚持应该能让对ORACLE
的认识达到一个新的高度。
本文参考资料
ORACLE 内核技术(JONATHAN LEWIS著)
ORACLE 内核技术揭秘(吕海波著)
DSI 402
DSI 402E