<a href="http://blog.csdn.net/changyanmanman/article/details/7312988">http://blog.csdn.net/changyanmanman/article/details/7312988</a>
本篇從資料塊邏輯結構角度入手,分析ITL中所包括的内容和與事務對應的資訊。
1、環境準備
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
Table created
SQL> insert into t2 values (1, 'id');
1 row inserted
SQL> insert into t2 values (2, 'iddf');
SQL> commit;
Commit complete
此時,對應的資料段資訊如下:
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where owner='SYS' and segment_name='T2';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 563 65536 8 1
從資料字典資訊看,Oracle為該資料段T配置設定了一個extents分區,其中包括8個資料塊。
2、無事務狀态下的ITL事務槽
首先,我們需要知道各個資料行對應的實體位置。我們可以使用dbms_rowid的包方法解析資料行rowid資訊。Rowid中實際包括幾個組成部分:相對檔案編号、對象編号、資料塊号和行slot号。
SQL> select id,dbms_rowid.rowid_relative_fno(rowid) fno,dbms_rowid.rowid_block_n
umber(rowid) bno,dbms_rowid.rowid_row_number(rowid) row_num from t2;
ID FNO BNO ROW_NUM
---------- ---------- ---------- ----------
1 4 566 0
2 4 566 1
SQL> alter system dump datafile 4 block 566;
System altered
--擷取trace跟蹤檔案位置名稱
SQL> select f_get_trace_name from dual;
F_GET_TRACE_NAME
---------------------------------------------------------------------
D:\ORACLE\PRODUCT\10.1.0\ADMIN\ORCL\UDUMP\orcl_ora_3736.trc
這個f_get_trace_name是一個函數,其代碼如下(注意此函數隻能在sys使用者下完成建立):
create or replace function F_GET_TRACE_NAME return varchar2 is
Result varchar2(1000);
begin
SELECT d.VALUE
|| '\'
|| LOWER (RTRIM (i.INSTANCE, CHR (0)))
|| '_ora_'
|| p.spid
|| '.trc' trace_file_name
into result
FROM (SELECT p.spid
FROM v$mystat m, v$session s, v$process p
WHERE m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,
(SELECT t.INSTANCE
FROM v$thread t, v$parameter v
WHERE v.NAME = 'thread'
AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,
(SELECT VALUE
FROM v$parameter
WHERE NAME = 'user_dump_dest') d;
return(Result);
end F_GET_TRACE_NAME;
我們打開跟蹤檔案,可以找到對應的itl資訊片段:
*** 2012-09-15 10:29:13.984
Start dump data blocks tsn: 4 file#: 4 minblk 566 maxblk 566
buffer tsn: 4 rdba: 0x01000236 (4/566)
scn: 0x0000.00a480fc seq: 0x01 flg: 0x00 tail: 0x80fc0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump: 0x01000236
Object id on Block? Y
seg/obj: 0xe357 csc: 0x00.a47f64 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000231 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.021.000039df 0x0080078c.1916.18 --U- 1 fsc 0x0000.00a47f7b
0x02 0x0004.018.000039e0 0x0080078f.1916.0c ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0x41d0264
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x041d0264
bdba: 0x01000236
76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f84
avsp=0x1f6e
tosp=0x1f6e
0xe:pti[0] nrow=2offs=0
0x12:pri[0] offs=0x1f8f
0x14:pri[1] offs=0x1f84
block_row_dump:
tab 0, row 0, @0x1f8f
tl: 9 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 2] 69 64
tab 0, row 1, @0x1f84
tl: 11 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 03
col 1: [ 4] 69 64 64 66
end_of_block_dump
End dump data blocks tsn: 4 file#: 4 minblk 566 maxblk 566
對每一個資料塊,都是包括ITL清單,用于描述目前資料塊上進行的事務資訊。在建立資料段對象的時候,包括initrans參數(預設值為1),就是表示該資料表對象的資料塊建立時候初始ITL事務槽的個數。Initrans參數在10g之後,基本上就失去了其效果的場景。Oracle對資料塊,初始都是建立兩個事務槽對象。當并發事務操作較多的時候,會進行自動的拓展,拓展到最大值255。
從上面的片段,我們可以看到該資料塊中,有兩個itl事務槽。Itl清單示連接配接的事務槽編号。
Xid是由三列使用十六進制編碼的數字清單示,該清單示對應的事務編号。在Oracle中,辨別一個事務是通過 usn.slot.sqn 表示。事務槽起作用的時候,每一個事務槽都與一個事務相關聯。
Flag對應的是目前事務槽的狀态資訊,标志着不同的事務狀态(下表資訊引自網絡資料)。
Flag取值
含義
-----
事務是活動的,或者在塊清除前送出事務
C---
事務已經送出并且清除了行鎖定
-B--
this undo record contains the undo for this ITL entry
--U-
事務已經送出(SCN已經是最大值),但是鎖定還沒有清除(快速清除)
---T
當塊清除的SCN被記錄時,該事務仍然是活動的,塊上如果有已經送出的事務,那麼在clean ount的時候,塊會被進行清除,但是這個塊裡面的事務不會被清除。
Lck表示該事務槽涉及到的記錄數目。Scn/Fsc:表示快速送出和已經送出的SCN編号。
從上面的ITL片段表示兩條記錄對應的事務已經送出,并且對應最大的SCN取值。
3、啟動單會話事務
我們首先觀察一下,當啟動一個會話事務的時候,ITL狀态情況。
SQL> select sid from v$mystat where rownum<2;
SID
----------
162
SQL> update t2 set vname='d' where id=1;
1 row updated
此時,對應事務資訊為。
SQL> select addr,xidusn,xidslot,xidsqn from v$transaction;
ADDR XIDUSN XIDSLOT XIDSQN
-------- ---------- ---------- ----------
6C278F2C 4 26 14820
這時候,我們嘗試dump出資料塊:
系統已更改。
情況如下:
Dump file d:\oracle\product\10.1.0\admin\orcl\udump\orcl_ora_7692.trc
Sat Sep 15 11:13:33 2012
ORACLE V10.1.0.2.0 - Production vsnsta=0
vsnsql=13 vsnxtr=3
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options
Windows XP Version V5.1 Service Pack 3
CPU : 2 - type 586, 2 Physical Cores
Process Affinity: 0x00000000
Memory (A/P) : PH:772M/2042M, PG:1903M/3935M, VA:1733M/2047M
Instance name: orcl
Redo thread mounted by this instance: 1
Oracle process number: 12
Windows thread id: 7692, image: ORACLE.EXE (SHAD)
*** 2012-09-15 11:13:33.078
*** ACTION NAME:() 2012-09-15 11:13:33.015
*** MODULE NAME:(SQL*Plus) 2012-09-15 11:13:33.015
*** SERVICE NAME:(SYS$USERS) 2012-09-15 11:13:33.015
*** SESSION ID:(162.13) 2012-09-15 11:13:33.015
scn: 0x0000.00a48c9b seq: 0x01 flg: 0x04 tail: 0x8c9b0601
frmt: 0x02 chkval: 0x7b0c type: 0x06=trans data
seg/obj: 0xe357 csc: 0x00.a48c78 itc: 2 flg: E typ: 1 - DATA
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.010.000039e4 0x008007a3.1916.22 C--- 0 scn 0x0000.00a48c5d
0x02 0x0004.01a.000039e4 0x008007a3.1916.29 ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0x40e0264
pbl: 0x040e0264
fseo=0x1f7c
0x12:pri[0] offs=0x1f7c
tab 0, row 0, @0x1f7c
tl: 8 fb: --H-FL-- lb: 0x2 cc: 2
col 1: [ 1] 64
tl: 11 fb: --H-FL-- lb: 0x0 cc: 2
第二行事務槽,鎖定影響記錄數量為1。對應的xid為 0x0004.01a.000039e4 。分析下轉換為十進制後分别為:4,26和14820。與v$transaction中對應的事務辨別一緻。說明0x02事務槽對應的是我們會話事務。
4、啟動第二個會話事務
當我們啟動第二個會話事務時,觀察情況。
151
SQL> update t2 set vname='fk' where id=2;
事務資訊和鎖資訊如下:
ADDR XIDUSN XIDSLOT XIDSQN
-------- ---------- ---------- ----------
6C2A1314 5 34 3361
SQL> select addr, kaddr, sid, type, id1, id2, lmode from v$lock where sid=151 or sid=162 order by sid;
ADDR KADDR SID TY ID1 ID2 LMODE
-------- -------- ---------- -- ---------- ---------- ----------
6C2A1314 6C2A1428 151 TX 327716 3361 6
6C237F30 6C237F48 151 TM 58199 0 3
6C278F2C 6C279040 162 TX 262152 14821 6
6C237E9C 6C237EB4 162 TM 58199 0 3
兩個事務同時作用在相同的資料塊上。我們dump出資料塊檢視ITL。
*** 2012-09-15 11:38:06.921
*** ACTION NAME:() 2012-09-15 11:38:06.875
*** MODULE NAME:(SQL*Plus) 2012-09-15 11:38:06.875
*** SERVICE NAME:(SYS$USERS) 2012-09-15 11:38:06.875
*** SESSION ID:(151.12329) 2012-09-15 11:38:06.875
scn: 0x0000.00a48fa4 seq: 0x01 flg: 0x04 tail: 0x8fa40601
frmt: 0x02 chkval: 0xfd0b type: 0x06=trans data
seg/obj: 0xe357 csc: 0x00.a48f48 itc: 2 flg: E typ: 1 - DATA
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0005.024.00000d21 0x00800017.09f1.19 ---- 1 fsc 0x0000.00000000
0x02 0x0004.008.000039e5 0x008007a6.1916.0d ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0x65a0264
pbl: 0x065a0264
fseo=0x1f73
avsp=0x1f70
tosp=0x1f70
0x14:pri[1] offs=0x1f73
tab 0, row 1, @0x1f73
col 1: [ 2] 66 6b
兩條ITL被占據。
5、第三個會話事務開啟
當我們啟動第三個會話事務,情況如何呢?
149
SQL> insert into t2 values (3,'kl');
鎖定情況如下:
SQL> select addr, kaddr, sid, type, id1, id2, lmode from v$lock where sid=149 or sid=151 or sid=162 order by sid;
ADDR KADDR SID TY ID1 ID2 LMODE
-------- -------- ---------- -- ---------- ---------- ----------
6C27349C 6C2735B0 149 TX 393221 2958 6
6C238058 6C238070 149 TM 58199 0 3
6C2A1314 6C2A1428 151 TX 327716 3361 6
6C237F30 6C237F48 151 TM 58199 0 3
6C278F2C 6C279040 162 TX 262152 14821 6
6C237E9C 6C237EB4 162 TM 58199 0 3
已選擇6行。
--對應v$transaction情況;
SQL> select addr,xidusn,xidslot,xidsqn from v$transaction;
ADDR XIDUSN XIDSLOT XIDSQN
-------- ---------- ---------- ----------
6C27349C 6 5 2958
6C278F2C 4 8 14821
6C2A1314 5 36 3361
事務開啟,新插入的資料依然在目前研究資料塊中。
SQL> select id, dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, dbms_rowid.rowid_row_number(rowid) row_num from t2;
ID FNO BNO ROW_NUM
---------- ---------- ---------- ----------
1 1 65266 0
2 1 65266 1
3 1 65266 2
事務槽dump結果。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.017.000085eb 0x008005d6.351e.11 ---- 1 fsc 0x0002.00000000
0x02 0x0009.019.000085e2 0x00800c4e.306a.2c ---- 1 fsc 0x0000.00000000
0x03 0x0002.008.000085fe 0x00800166.3192.0b ---- 1 fsc 0x0000.00000000
當目前準備的事務槽個數小于資料塊進行的事務個數時,會進行事務槽自動拓展。
6、事務清理
當事務結束,事務槽清理。
0x01 0x0007.02a.000085d4 0x00800ca8.35fc.09 C--- 0 scn 0x078c.7f2ddad3
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
7、結論
在Oracle資料塊上,ITL是一個重要的部分。它與會話、事務、多版本一緻度等特性密切相關