DB-hub Technology Oracle Lab – Storage Structure

Oracle Lab – Storage Structure

1.实验一

1.1.dump数据块到trace文件

CREATE TABLE T_TESTBLOCK( ID NUMBER, NAME VARCHAR(4) ) ;

INSERT INTO T_TESTBLOCK VALUES (1, 'a');
INSERT INTO T_TESTBLOCK VALUES (2, 'b');
INSERT INTO T_TESTBLOCK VALUES (3, 'c');
COMMIT;

SELECT ROWID, DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) REL_FNO, DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) BLOCKNO FROM T_TESTBLOCK;

ROWID                 REL_FNO    BLOCKNO
------------------ ---------- ----------
AAASTiAABAAAZXhAAA          1     103905
AAASTiAABAAAZXhAAB          1     103905
AAASTiAABAAAZXhAAC          1     103905

这3行数据都在1号数据文件的第103905个块。将该数据块dump出来:

ALTER SYSTEM DUMP DATAFILE 1 BLOCK 103905;

set pages 500
set linesize 500
col name for a25
col value for a75
select name, value from vdiag_info;

select name, value from vdiag_info where name like 'Default%';

NAME                      VALUE
------------------------- --------------------------------------------------------------------------------
Diag Enabled              TRUE
ADR Base                  /oracle/app/oracle
ADR Home                  /oracle/app/oracle/diag/rdbms/hamster/HAMSTER
Diag Trace                /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace
Diag Alert                /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/alert
Diag Incident             /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/incident
Diag Cdump                /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/cdump
Health Monitor            /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/hm
Default Trace File        /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_62379.trc
Active Problem Count      0
Active Incident Count     0
cd /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/
more HAMSTER_ora_62379.trc

1.2.块头信息

Block dump from disk:
buffer tsn: 0 rdba: 0x004195e1 (1/103905)
scn: 0x1e5a43 seq: 0x01 flg: 0x04 tail: 0x5a430601
frmt: 0x02 chkval: 0xdff5 type: 0x06=trans data
  • buffer tsn: 0 表示该块对应的表空间号,这里是0号表空间
  • rdba: 0x004195e1 (1/103905) 其中,rdba(relative data block address)表示相对数据块地址,其中(1/103905)表示该块为1号数据文件第103905个块,用4个字节32位来表示,前10位为相对数据文件号,后22位为块号。01c00083(十六进制)=0000 0000 0100 0001 1001 0101 1110 0001(二进制),不难看出前10位(0000 0000 01)转换成十进制就是1,后22位(00 0001 1001 0101 1110 0001)转换成十进制就是103905。rdba在数据块中的offset是4,即rdba存在于数据块中的第5-9字节中(offset从0开始算),数据块中的每个部分在数据块中的偏移量通过BBED可以展示出来
  • scn: 0x1e5a43 表示数据块头部SCN. 总共占用6个字节,前2个字节(0000)表示SCN Wrap,后4个字节(00752951)表示SCN Base。如果SCN Base达到了4个字节表示的最大值,SCN Wrap+1,SCN Base清0。在数据块中的offset是8。这里的SCN号为7678289
  • seq: 0x01 表示Sequence number即日志序列号。在数据块中的offset是14
  • flg: 0x04 flg即Flag,其中,0x01代表New block即新建块;0x02代表Delayed Logging Change advanced SCN即数据块延迟清洗推进scn和seq;0x04代表Check value即设置校验和;0x08代表Temporary block即临时块。其它值都是01、02、04、08的组合。在数据块中的offset是15
  • tail: 0x5a430601 即tail check,存放于数据块的最后4个字节,用于数据块一致性检查。tail check的组成:SCN Base的低2个字节+type+seq。即tail:0x5a430601=5a43+06+01
  • frmt: 0x02 代表块格式。01表示Oracle 7,02表示Oracle 8+
  • chkval: 0xdff5 代表块检查值。如果参数DB_BLOCK_CHECKSUM=TRUE,那么数据块在读入buffer和写回数据文件之前都要做检查计算,如果计算值和数据块中记录的计算值不匹配就会标记该块是坏块
  • type: 0x06=trans data 代表块类型,参考以下的表格:

1.3.事务列表

Block header dump:  0x004195e1
 Object id on Block? Y
 seg/obj: 0x124df  csc:  0x00000000001e5a42  itc: 2  flg: -  typ: 2 - INDEX
     fsl: 0  fnx: 0x0 ver: 0x01

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc  0x0000.00000000
0x02   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn  0x00000000001e5a42
  • Object id on Block? Y 表示该块是否属于某个对象

  • seg/obj: 0x124df 表示该数据块中对象的OBJECT_ID。

select to_number('124df','xxxxxx') from dual;
select to_number('124df','xxxxxx') from dual;

TO_NUMBER('124DF','XXXXXX')
---------------------------
                      74975


col object_name for a20
select object_name, object_type from dba_objects where object_id=74975;

OBJECT_NAME          OBJECT_TYPE
-------------------- -----------------------
IDX_SALES_INFO       INDEX
  • csc: 0x00000000001e5a42 表示SCN at last Block CleanOut,表示最后一次块清除(Block CleanOut)时候的SCN
  • itc: 2 块中ITL slot的数量,0x01 和 0x02
  • flg: – 0表示此块被放置在自由列表(freelist)中,E指的是ASSM
  • typ: 2 – INDEX 表示数据库块的类型,1表示数据,2表示索引

ITL(Interested Transaction List,事务槽)

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc  0x0000.00000000
0x02   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn  0x00000000001e5a42

ITL是Oracle数据块内部的一个组成部分,用来记录在该块上发生的所有事务。1个ITL可以看作是一个记录,在一个时间,可以记录一个事务(包括提交或者未提交事务)。当然,如果这个事务已经提交,那么这个ITL的位置就可以被反复使用了,因为LTL与记录非常类似,所以,有的时候也叫ITL槽位。

ITL位于数据块头(Block Header),ITL事务槽由槽位号(Itl)、Xid(Transaction ID)、Uba(Undo Block Address)、Flag、Lck和Scn/Fsc几个部分组成。Oracle的每个数据块中都有一个或者多个事务槽,每一个对数据块的并发访问事务都会占用一个事务槽。对于已经提交的事务,ITL槽位不会马上被覆盖,因为一致性读可能会用到这个信息,一致性读的时候,可能需要从这里获得回滚段的入口,并从回滚段中获得一致性读。

当发出一条SQL语句时,Oracle会记录下这个时刻的SCN,然后在Buffer Cache中查找需要的BLOCK,或者从磁盘上读。当别的会话修改了数据,或者正在修改数据时,就会在相应的块上记录ITL,此时Oracle发现ITL中记录的SCN大于SELECT时刻的SCN,那么Oracle就会根据ITL中的Uba找到Undo信息获得该BLOCK的前镜像,然后在Buffer Cache中构造出CR(consistent read)块,此时Oralce也会检查构造出来的BLOCK中ITL记录的SCN。如果SCN还大于SELECT时刻的SCN,那么一直重复构造前镜像,然后Oracle找到前镜像BLOCK中的ITL的SCN是否小于SELECT的SCN,同时检查这个事务有没有提交或者回滚。如果没有,那么继续构造前镜像,直到找到需要的BLOCK,如果在构造前镜像的过程中所需的Undo信息被覆盖了,就会报快照过旧的错误。

如果一个事务一直没有提交,那么这个事务将一直占用一个ITL槽位。如果这个事务已经提交,那么,ITL槽位中还保存的有这个事务提交时候的SCN号。

ITL的个数受参数INITRANS控制,最大ITL个数受MAXTRANS控制(Oracle 10g已废弃MAXTRANS,默认最大支持255个并发)。在一个块内部,默认分配了2个ITL的个数。如果这个块内还有空闲空间(Free Space),那么Oracle是可以利用这些空闲空间并再次分配ITL。如果没有了空闲空间,那么这个块会因为不能分配新的ITL可能发生ITL等待,即enq: TX – allocate ITL entry等待事件。

在并发量特别大的系统中,最好分配足够的ITL个数,或者设置足够的PCTFREE,保证ITL能扩展。但是,PCTFREE有可能是被行数据给消耗掉的,如UPDATE,所以,也有可能导致块内部的空间不够而导致ITL等待。对于表(数据块)来说,INITRANS这个参数的默认值是1。对于索引(索引块)来说,这个参数默认值是2。

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc  0x0000.00000000
0x02   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn  0x00000000001e5a42
  • Itl:ITL事务槽编号
  • Xid:代表对应的事务id(transac[X]tion identified),在回滚段事务表中有一条记录和这个事务对应。Xid由3列使用十六进制编码的数字列表示,分别是:Undo Segment Number + Transaction Table Slot Number + Wrap,即由undo段号+undo槽号+undo槽号的覆盖次数三部分组成,即usn.slot.sqn。
INSERT INTO T_TESTBLOCK VALUES (4, 'd');

不要commit.

SQL> SELECT ROWID, DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) REL_FNO, DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) BLOCKNO FROM T_TESTBLOCK;

ROWID                 REL_FNO    BLOCKNO
------------------ ---------- ----------
AAASTiAABAAAZXhAAA          1     103905
AAASTiAABAAAZXhAAB          1     103905
AAASTiAABAAAZXhAAC          1     103905
AAASTiAABAAAZXhAAD          1     103905

SQL> ALTER SYSTEM DUMP DATAFILE 1 BLOCK 103905;

System altered.

SQL> select value from v$diag_info where name like 'Default%';

VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_88283.trc

SQL> !more /oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_88283.trc

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0003.020.00000509  0x01000b87.0167.09  --U-    3  fsc 0x0000.001e5edd
0x02   0x0005.018.0000053a  0x010007f9.016d.1b  ----    1  fsc 0x0000.00000000

Xid: 0x0005.018.0000053a 十进制:5.24.1338,和查询V$TRANSACTION的结果是相对应的。

SQL>  SELECT XIDUSN, XIDSLOT, XIDSQN, UBAFIL, UBABLK, UBASQN, UBAREC FROM V$TRANSACTION;

    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
         5         24       1338          4       2041        365         27
  • Uba:即Undo Block Address,该事务对应的回滚段地址,记录了最近一次的该记录的前镜像(修改前的值)。Uba组成:Undo块地址(undo文件号和数据块号)+回滚序列号+回滚记录号。多版本一致读是Oracle保证读操作不会被事务阻塞的重要特性。当Server Process需要查询一个正在被事务修改,但是尚未提交的数据时,就根据ITL上的Uba定位到对应Undo前镜像数据位置。这里的Uba为:0x010007f9.016d.1b,其中:
    0x010007f9(16进制)=0000 0001 0000 0000 0000 0111 1111 1001(2进制,共32位,前10位代表文件号,后22位代表数据块号)=文件号为4,块号为2041(10进制);
    016d(16进制)=365(10进制);
    1b(16进制)=27(10进制)。
    Uba的值可以从V$TRANSACTION查询出来:
SQL> SELECT UBAFIL 回滚段文件号,UBABLK 数据块号,UBASQN 回滚序列号,UBAREC 回滚记录号 FROM v$transaction ;

回滚段文件号   数据块号 回滚序列号 回滚记录号
------------ ---------- ---------- ----------
           4       2041        365         27
  • Flag:事务标志位,即当前事务槽的状态信息。这个标志位记录了这个事务的操作状态,各个标志的含义分别是:
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0003.020.00000509  0x01000b87.0167.09  --U-    3  fsc 0x0000.001e5edd
0x02   0x0005.018.0000053a  0x010007f9.016d.1b  ----    1  fsc 0x0000.00000000

  • Lck:表示这个事务所影响的行数,锁住了几行数据,对应有几个行锁。在这里,可以看到01号事务槽Lck为3,因为该事务槽中的事务Flag为U,证明该事务已经提交,但是锁还没有清除。

  • Scn/Fsc:Scn表示提交时的SCN。Commit SCN或者快速提交(Fast Commit,Fsc)的SCN。Scn=SCN of commited TX;Fsc=Free space credit(bytes)。
    对于一个Oracle事务来说,可以是快速提交、也可以是延迟提交,目的都是为了提高提交的速度。提交以后,Oracle需要对ITL事务槽、每一行的锁定标记进行清除。如果是快速提交,那么在提交的时候,会将事务表和每一个数据块的ITL槽进行清除。但是锁定标记可能没有清除,等下次用到的时候再进行清除。如果是延迟提交,那么在提交的时候,只是将事务表进行清除,并没有对ITL事务槽进行清除,每一行的锁定标记也没有清除。因此,C和U的情况特别多。块清除的过程并不包括每个行的锁定标记的清除,主要指的是ITL的清除。

① 事务槽中首先记录的是XID和UBA,只有在提交以后,当对这个数据块进行CLEANOUT的时候,才会更新FLAG和SCN。因此,Oracle总是以事务表中对这个数据块的SCN以及FLAG为准。

② 一个事务开始以后,在一个数据块上得到一个事务槽,那么在这个事务提交以前,这个事务槽会一直占用,直到这个事务提交才会释放这个事务槽。

③ 只有在已经提交以后,这个ITL事务槽中的SCN才会有数值。

④ 事务是否已经提交、事务对应的SCN,这些信息都是以回滚段事务表中的为主,事务槽中的不准确。

⑤ 事务槽中的事务ID和UBA地址是准确的。

⑥ 事务槽中的事务ID和回滚段中的事务ID肯定不是一样的,不同回滚段中的事务ID也一定不一样。

1.3.用户数据头区(data_block_dump)

行目录(Row Directory)记录了数据块里每一行相对于起点的偏移量,Oracle正是通过行目录找到所需的数据行。

bdba: 0x004195e1
data_block_dump,data header at 0x7f319d4a605c
===============
tsiz: 0x1fa0
hsiz: 0x1a
pbl: 0x7f319d4a605c
     76543210
flag=--------
ntab=1
nrow=4
frre=-1
fsbo=0x1a
fseo=0x1f80
avsp=0x1f62
tosp=0x1f62
0xe:pti[0]      nrow=4  offs=0
0x12:pri[0]     offs=0x1f98
0x14:pri[1]     offs=0x1f90
0x16:pri[2]     offs=0x1f88
0x18:pri[3]     offs=0x1f80
block_row_dump:
tab 0, row 0, @0x1f98
tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [ 1]  61
tab 0, row 1, @0x1f90
tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 03
col  1: [ 1]  62
tab 0, row 2, @0x1f88
tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 04
col  1: [ 1]  63
tab 0, row 3, @0x1f80
tl: 8 fb: --H-FL-- lb: 0x2  cc: 2
col  0: [ 2]  c1 05
col  1: [ 1]  64
  • bdba: 0x004195e1 block dba/rdba(数据块地址),用4个字节32位来表示,前10位为相对数据文件号,后22位为块号。01c00083(十六进制)=0000 0000 0100 0001 1001 0101 1110 0001(二进制),可以看到前10位(0000 0000 0100)转换成十进制就是1,后22位(00 0001 1001 0101 1110 0001)转换成十进制就是1039051,即1号文件103905号数据块

  • tsiz: 0x1fa0 Total Data Area Size(数据区的大小,块的总大小),转换为10进制即8096字节

  • hsiz: 0x1a 数据块头大小,转换为10进制即26字节
  • pbl: 0x7f319d4a605c 指向这个数据块在内存中映像的指针
  • flag=——– N=pcrfree hit(clusters);F=do not put on free list;K=flushable cluster keys
  • ntab=1 number of tables (>1 is a cluster)
  • nrow=4 即行数,这里表示这个表有4行数据
  • frre=-1 first free row index entry, -1=you have to add one(没有创建索引)
  • fsbo=0x1a free space begin offset(空闲空间起始位置),叫起始空间:可以存放数据空间的起始位置(即定义了数据层中空闲空间的起始offset)
  • fseo=0x1f80 free space end offset(空闲空间结束位置),叫结束空间:可以存放数据空间的结束位置(即定义了数据层中空闲空间的结束offset)
  • avsp=0x1f62 available space in the block(可用空间),叫空闲空间:定义了数据层中空闲空间的字节数
  • tosp=0x1f62 total available space when all txs commit,叫最终空闲空间:定义了ITL中事务提交后,数据层中空闲空间的字节数
  • 0xe:pti[0] nrow=4 offs=0 Table directory,整个表的开始,该块有3条记录
  • 0x12:pri[0] offs=0x1f98 第1条记录在偏移量为0x1f98的地方,下面两行以此类推
  • 0x14:pri[1] offs=0x1f90
  • 0x16:pri[2] offs=0x1f88

1.4.用户数据区(block_row_dump)

block_row_dump:
tab 0, row 0, @0x1f98
tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [ 1]  61
tab 0, row 1, @0x1f90
tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 03
col  1: [ 1]  62
tab 0, row 2, @0x1f88
tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 04
col  1: [ 1]  63
end_of_block_dump
  • tab 0, row 0, @0x1f98 第一个表第一行的位置,定义了该表在行索引中的起始插槽号
  • lb: 0x1 表示lock byte。锁定该行的这个事务在ITL的入口,0x1说明事务在该数据行上的锁还没清除,并且该锁指向01号事务槽。lb: 0x0说明事务在该数据行上的锁已经被清除
  • tl: 8 表示Row Size(number of bytes plus data)
  • fb Flag Byte
    K- Cluster key
    H- head of row piece
    D- Deleted row
    F- first data piece
    L- last data piece
    P- First column cintinues from previous row N- Last column cintinues in next piece
    当DELETE一行数据的时候,数据并不是物理地被删除,而是把该行标记为删除,这个时候fb应该是–HDFL–而不是原来的–H-FL–。
  • cc 表示number of columns in this Row piece

关于行中的数据,可以以第一行来说明一下。由于表的第2行数据为(2,’b’),所以可以使用dump函数来验证一下。dump函数可以按指定的格式显示输入数据的内部表示,这里显示16进制:

tl: 8 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 03
col  1: [ 1]  62
SQL> select dump(2,16),dump('b',16) from dual;

DUMP(2,16)        DUMP('B',16)
----------------- ----------------
Typ=2 Len=2: c1,3 Typ=96 Len=1: 62

2.实验二

2.1.创建测试表

create table t4 (id number, vname varchar2(10));
insert into t4 values (1, 'id');
insert into t4 values (2, 'ix');

查询数据段:

select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where owner='SYS' and segment_name='T4';

HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS
----------- ------------ ---------- ---------- ----------
          1       104088      65536          8          1

commit;

2.1.无事务状态下的ITL

使用dbms_rowid包的方法解析数据行rowid信息。

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

       ID        FNO        BNO    ROW_NUM
---------- ---------- ---------- ----------
         1          1     104089          0
         2          1     104089          1

两个数据行均在文件1的104089数据块上。我们接下来使用dump数据块的方法,将该块的逻辑结构dump到当前会话对应的跟踪文件中。

alter system dump datafile 1 block 104089;
select value from v$diag_info where name like 'Default%';
VALUE
--------------------------------------------------------------------------------
/oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_31103.trc

打开跟踪文件,可以找到对应的itl信息片段。

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0006.018.00000534  0x0100130d.01a1.09  C---    0  scn  0x00000000001e9326
0x02   0x0006.012.00000534  0x0100130d.01a1.15  --U-    1  fsc 0x0000.001e947b

数据块默认是创建两个ITL对象。当并发事务操作较多的时候,会进行自动的拓展,最大值是255。

Xid是由三列使用十六进制编码的数字列表示,该列表示对应的事务编号。在Oracle中,标识一个事务是通过usn.slot.sqn表示。事务槽起作用的时候,每一个事务槽都与一个事务相关联。

Uba应当为undo block address的缩写。多版本一致读是Oracle保证读操作不会被事务阻塞的重要特性。当Server Process需要查询一个正在被事务修改,但是尚未提交的数据时,就根据ITL上的uba定位到对应Undo前镜像数据位置。

Flag对应的是当前事务槽的状态信息,标志着不同的事务状态(参考实验一)。

Lck表示该事务槽涉及到的记录数目。Scn/Fsc:表示快速提交和已经提交的SCN编号。

2.2.启动单会话事务

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

       SID
----------
       271

SQL> update t4 set vname='ig' where id=1;

1 row updated.

事务信息和锁信息如下:

SQL> select ADDR, XIDUSN, XIDSLOT, XIDSQN from v$transaction;

ADDR                 XIDUSN    XIDSLOT     XIDSQN
---------------- ---------- ---------- ----------
000000006424A120         10         24       1224

dump出数据块,ITL如下:

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

        ID        FNO        BNO    ROW_NUM
---------- ---------- ---------- ----------
         1          1     104089          0
         2          1     104089          1

SQL> alter system dump datafile 1 block 104089;

System altered.

SQL> select value from v$diag_info where name like 'Default%';

/oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_32255.trc

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0006.005.0000053b  0x01000492.01a2.1d  --U-    2  fsc 0x0000.001ea045
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

第二行事务槽,锁定影响记录数量为2。对应的xid为0x0006.005.0000053b。转换为十进制后分别为:6,5和1339。与v$transaction中对应的事务标识一致。说明0x01事务槽对应的是我们会话事务。

2.3.启动第二个会话事务

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

       SID
----------
       31

SQL> update t4 set vname='ik' where id=2;

1 row updated.

事务信息和锁信息如下:

SQL> select ADDR, XIDUSN, XIDSLOT, XIDSQN from vtransaction;

ADDR                 XIDUSN    XIDSLOT     XIDSQN
---------------- ---------- ---------- ----------
000000006424A120         10         24       1224
000000006433F040          4         25        982


select addr, kaddr, sid, type, id1, id2, lmode from vlock where sid=17 or sid=271 or sid =31 order by 1;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE
---------------- ---------------- ---------- -- ---------- ---------- ----------
000000006424A120 000000006424A1A8        271 TX     655384       1224          6
000000006433F040 000000006433F0C8         31 TX     262169        982          6
000000006741F710 000000006741F790         31 AE        133          0          4
000000006741F958 000000006741F9D8        271 AE        133          0          4
000000006741FB88 000000006741FC08         17 AE        133          0          4
00007F3BAA25B538 00007F3BAA25B5A8         31 TM      74986          0          3
00007F3BAA25B538 00007F3BAA25B5A8        271 TM      74986          0          3

dump出数据块,ITL如下:

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

        ID        FNO        BNO    ROW_NUM
---------- ---------- ---------- ----------
         1          1     104089          0
         2          1     104089          1
SQL> alter system dump datafile 1 block 104089;

System altered.

SQL> select value from v$diag_info where name like 'Default%';

/oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_31103.trc

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0004.019.000003d6  0x01000333.016b.05  ----    1  fsc 0x0000.00000000
0x02   0x000a.018.000004c8  0x01000405.0100.0b  ----    1  fsc 0x0000.00000000

4.25.982
10.24.1224

两条ITL被占据!

2.4.启动第三个会话事务

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

       SID
----------
       253

SQL> insert into t4 values (3,'i3');

1 row created.

事务信息和锁信息如下:

SQL> select ADDR, XIDUSN, XIDSLOT, XIDSQN from vtransaction;
ADDR                 XIDUSN    XIDSLOT     XIDSQN
---------------- ---------- ---------- ----------
000000006424A120         10         24       1224
000000006433F040          4         25        982
00000000643637D0          5          8       1343



select addr, kaddr, sid, type, id1, id2, lmode from vlock where sid=17 or sid=271 or sid =31 or sid=253 order by 1;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE
---------------- ---------------- ---------- -- ---------- ---------- ----------
000000006424A120 000000006424A1A8        271 TX     655384       1224          6
000000006433F040 000000006433F0C8         31 TX     262169        982          6
00000000643637D0 0000000064363858        253 TX     327688       1343          6
000000006741F710 000000006741F790         31 AE        133          0          4
000000006741F958 000000006741F9D8        271 AE        133          0          4
000000006741FB88 000000006741FC08         17 AE        133          0          4
000000006741FFE8 0000000067420068        253 AE        133          0          4
00007F28693135F8 00007F2869313668         31 TM      74986          0          3
00007F28693135F8 00007F2869313668        253 TM      74986          0          3
00007F28693135F8 00007F2869313668        271 TM      74986          0          3

dump出数据块,ITL如下:

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

        ID        FNO        BNO    ROW_NUM
---------- ---------- ---------- ----------
         1          1     104089          0
         2          1     104089          1
         3          1     104089          2

SQL> alter system dump datafile 1 block 104089;

System altered.

SQL> select value from v$diag_info where name like 'Default%';

/oracle/app/oracle/diag/rdbms/hamster/HAMSTER/trace/HAMSTER_ora_31103.trc

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0004.019.000003d6  0x01000333.016b.05  ----    1  fsc 0x0000.00000000
0x02   0x000a.018.000004c8  0x01000405.0100.0b  ----    1  fsc 0x0000.00000000
0x03   0x0005.008.0000053f  0x010000c4.016e.32  ----    1  fsc 0x0000.00000000
4.25.982
10.24.1224
5.8.1343

增加一个Itl, 当前准备的事务槽个数小于数据块进行的事务个数时,会进行事务槽自动拓展。