從Dump資料塊看ITL

realkid4發表於2012-02-16

 

Oracle中,資料塊block上存在記錄事務資訊的ITL(Interest Transaction List)。當一個資料庫事務涉及到資料塊對應的資料時,就會在當前資料塊塊頭(block head)後面的ITL中記錄上相應的資訊。

 

本篇從資料塊邏輯結構角度入手,分析ITL中所包括的內容和與事務對應的資訊。

 

1、 環境準備

 

在這裡,我們準備一個簡單的資料表作為實驗物件。

 

 

SQL> select * from v$version;

 

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

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

 

 

SQL> create table t (id number, vname varchar2(10));

Table created

 

SQL> insert into t values (1, 'id');

1 row inserted

 

SQL> insert into t values (2, 'iddf');

1 row inserted

 

SQL> commit;

Commit complete

 

 

此時,對應的資料段資訊如下:

 

 

SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SYS' and segment_name='T';

 

HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS

----------- ------------ ---------- ---------- ----------

          1        65265      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_number(rowid) bno, dbms_rowid.rowid_row_number(rowid) row_num from t;

 

        ID        FNO        BNO    ROW_NUM

---------- ---------- ---------- ----------

         1          1      65266          0

         2          1      65266          1

 

 

兩個資料行均在檔案1的65266資料塊上。我們接下來使用dump資料塊的方法,將該塊的邏輯結構dump到當前會話對應的跟蹤檔案中。

 

 

SQL> alter system dump datafile 1 block 65266;

System altered

 

--獲取trace跟蹤檔案位置名稱

SQL> select f_get_trace_name from dual;

F_GET_TRACE_NAME

------------------------------------------------------

C:\TOOL\ORACLE\ORACLE\PRODUCT\10.2.0\ADMIN\OTS\UDUMP\ots_ora_5488.trc

 

 

我們開啟跟蹤檔案,可以找到對應的itl資訊片段。

 

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0007.02a.000085d4  0x00800ca8.35fc.09  --U-    2  fsc 0x0000.7f2ddad3

0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

 

 

對每一個資料塊,都是包括ITL列表,用於描述當前資料塊上進行的事務資訊。在建立資料段物件的時候,包括initrans引數(預設值為1),就是表示該資料表物件的資料塊建立時候初始ITL事務槽的個數。

 

Initrans引數在10g之後,基本上就失去了其效果的場景。Oracle對資料塊,初始都是建立兩個事務槽物件。當併發事務操作較多的時候,會進行自動的擴充,擴充到最大值255。

 

從上面的片段,我們可以看到該資料塊中,有兩個itl事務槽。Itl列表示連線的事務槽編號。

 

Xid是由三列使用十六進位制編碼的數字列表示,該列表示對應的事務編號。在Oracle中,標識一個事務是透過usn.slot.sqn表示。事務槽起作用的時候,每一個事務槽都與一個事務相關聯。

 

Uba應當為undo block address的縮寫。多版本一致讀是Oracle保證讀操作不會被事務阻塞的重要特性。當Server Process需要查詢一個正在被事務修改,但是尚未提交的資料時,就根據ITL上的uba定位到對應Undo前映象資料位置。

 

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

----------

       139

 

SQL> update t set vname='d' where id=1;

1 row updated

 

 

此時,對應事務資訊為。

 

 

SQL> select * from v$transaction;

 

ADDR         XIDUSN    XIDSLOT     XIDSQN  

-------- ---------- ---------- ----------

27FB6AAC          9         25      34274  

 

 

這時候,我們嘗試dump出資料塊,ITL鏈情況如下:

 

 

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0007.02a.000085d4  0x00800ca8.35fc.09  C---    0  scn 0x078c.7f2ddad3

0x02   0x0009.019.000085e2  0x00800c4e.306a.2c  ----    1  fsc 0x0000.00000000

 

 

第二行事務槽,鎖定影響記錄數量為1。對應的xid為0x0009.019.000085e2。分析下轉換為十進位制後分別為:9,25和34274。與v$transaction中對應的事務標識一致。說明0x02事務槽對應的是我們會話事務。

 

 

4、啟動第二個會話事務

 

當我們啟動第二個會話事務時,觀察情況。

 

 

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       147

 

SQL> update t set vname='fk' where id=2;

1 row updated

 

 

事務資訊和鎖資訊如下:

 

 

SQL> select * from v$transaction;

 

ADDR         XIDUSN    XIDSLOT     XIDSQN   

-------- ---------- ---------- ----------

27FB6AAC          9         25      34274                              

27FB6FE0          3         23      34283  

 

SQL> select addr, kaddr, sid, type, id1, id2, lmode from v$lock where sid=147 or sid=139 order by sid;

 

ADDR     KADDR           SID TYPE        ID1        ID2      LMODE

-------- -------- ---------- ---- ---------- ---------- ----------

27FB6AAC 27FB6BC8        139 TX       589849      34274          6

27F3F1D8 27F3F1F0        139 TM       112888          0          3

27FB6FE0 27FB70FC        147 TX       196631      34283          6

27F3F29C 27F3F2B4        147 TM       112888          0          3

 

 

兩個事務同時作用在相同的資料塊上。我們dump出資料塊檢視ITL。

 

 

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

 

 

兩條ITL被佔據。

 

5、第三個會話事務開啟

 

當我們啟動第三個會話事務,情況如何呢?

 

 

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       137

 

SQL> insert into t values (3,'kl');

1 row inserted

 

 

鎖定情況如下:

 

 

SQL> select addr, kaddr, sid, type, id1, id2, lmode from v$lock where sid=147 or sid=139 or sid=137 order by sid;

 

ADDR     KADDR           SID TYPE        ID1        ID2      LMODE

-------- -------- ---------- ---- ---------- ---------- ----------

27F3F360 27F3F378        137 TM       112888          0          3

27F87B2C 27F87C48        137 TX       131080      34302          6

27FB6AAC 27FB6BC8        139 TX       589849      34274          6

27F3F1D8 27F3F1F0        139 TM       112888          0          3

27FB6FE0 27FB70FC        147 TX       196631      34283          6

27F3F29C 27F3F2B4        147 TM       112888          0          3

 

6 rows selected

 

 

--對應v$transaction情況;

 

ADDR         XIDUSN    XIDSLOT     XIDSQN   

-------- ---------- ---------- ---------- -

27F87B2C          2          8      34302     

27FB6AAC          9         25      34274   

27FB6FE0          3         23      34283           

 

 

 

事務開啟,新插入的資料依然在當前研究資料塊中。

 

 

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 t;

 

        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、事務清理

 

當事務結束,事務槽清理。

 

 

SQL> alter system dump datafile 1 block 65266;

 

System altered

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

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是一個重要的部分。它與會話、事務、多版本一致度等特性密切相關

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-716353/,如需轉載,請註明出處,否則將追究法律責任。

相關文章