ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 从Dump数据块看ITL

从Dump数据块看ITL

原创 Linux操作系统 作者:realkid4 时间:2012-02-16 00:45:31 3 删除 编辑

 

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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7552510