ITPub博客

首页 > 数据库 > Oracle > 关于事务对数据块的操作过程的分析和试验(1)(转)

关于事务对数据块的操作过程的分析和试验(1)(转)

原创 Oracle 作者:flysky0814 时间:2007-12-04 13:32:04 0 删除 编辑

事务和数据块

这里主要想通过试验来推断Oracle的事务在数据块(Oracle中存储的最小单位)上一些微观操作,以便于更好的理解Oracle的事务控制、一致性处理及锁冲突。

创建测试表:

SQL> create table t_multiver (a number, b number);
 
Table created.
 
SQL> insert into t_multiver values (1,1);
 
1 row created.
 
SQL> insert into t_multiver values (2,2);
 
1 row created.
 
SQL> insert into t_multiver values (3,3);
 
1 row created.
 
SQL>
SQL> commit;
 
Commit complete.

首先,看一下数据块上和记录有关的标示,dump一个数据块看看:

SQL> alter system dump datafile 5 block 50816;
 
System altered.

看看Dump出来的内容:

Block header dump:  0x0140c70f
 Object id on Block? Y
 seg/obj: 0xe46c  csc: 0x00.a4462b75  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x140c709 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0008.020.0000192f  0x0080051a.059f.34  --U-    3  fsc 0x0000.a4462b7a
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
 
data_block_dump,data header at 0x9f75664
===============
tsiz: 0x1f98
hsiz: 0x18
pbl: 0x09f75664
bdba: 0x0140c70f
     76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f7d
avsp=0x1f65
tosp=0x1f65
0xe:pti[0] nrow=3   offs=0
0x12:pri[0]        offs=0x1f8f
0x14:pri[1]        offs=0x1f86
0x16:pri[2]        offs=0x1f7d
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]  c1 02
tab 0, row 1, @0x1f86
tl: 9 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 03
col  1: [ 2]  c1 03
tab 0, row 2, @0x1f7d
tl: 9 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 04
col  1: [ 2]  c1 04
end_of_block_dump
End dump data blocks tsn: 5 file#: 5 minblk 50959 maxblk 50959

注意红色黑体部分和Interested Transaction Slot (ITS) 部分。

CSC:Cleanout SCN,最后一次对该数据块进行CleanoutSCN

Itc: Itl countItl的数量。看到下面的Itl列表中有两条记录,所以是2

ItlInterested Transaction List。直译过来就是感兴趣的事物列表。也就是对该数据块产生影响的事物。对应的数字是序列号。

Xid :Transaction ID。事务ID号。在相应回滚段的事物信息表中对应唯一一条记录。

UbaUndo Block Address。回滚数据块地址,该地址对应了该事务在回滚段中记录的回滚数据的地址。

分解该地址:0x0080051a.059f.34

第一段是回滚数据块的地址,包括回滚段文件号和数据块号;第二段是回滚序列号;第三段是回滚记录号。

Flag事务标志位。这个标志位就记录了这个事务的操作,各个标志的含义分别是:

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

Scn/Fsc:快速提交(Fast Commit Fsc)的SCN或者Commit SCN

每条记录中的行级锁对应Itl条目lb,对应于Itl列表中的序号,即那个事务在该记录上产生的锁。

回滚段

下面再看看回滚段中是如何记录的:

更新数据(数据更新前b=115):

SQL> conn demo/demo
Connected.
SQL> alter system flush buffer_cache;
 
System altered.
 
SQL>
SQL> update t_multiver set b=116 where a=1;
 
1 row updated.

查看事务信息:

select UBAFIL, UBABLK, UBASQN, UBAREC from v$transaction;
 
11  80  886  16

UBAFIL:回滚段文件号;

UBABLK:数据块号;

UBASQN:回滚序列号;

UBAREC:回滚记录号。

这些数据就对应了数据块中的Uba

也可以通过以下方式从数据块的Uba中获取到回滚段这些信息:

0x02c00050.0376.10

0376即回滚序列号,10即回滚记录号。它们都是16进制。

下面获取文件号和数据块号:

SQL> set serveroutput on
SQL> declare
  2  v_file number;
  3  v_block number;
  4  begin
  5  v_file := dbms_utility.data_block_address_file(to_number('02c00050','xxxxxxxx'));
  6  v_block := dbms_utility.data_block_address_block(to_number('02c00050','xxxxxxxx'));
  7  dbms_output.put_line('file id: '||v_file);
  8  dbms_output.put_line('block id: '||v_block);
  9  end;
 10  /
file id: 11
block id: 80
 
PL/SQL procedure successfully completed.

Dump出数据块和回滚块:

SQL> alter system dump datafile 5 block 50959;
 
System altered.
 
SQL> conn demo/demo
Connected.
SQL>
SQL> alter system dump datafile 11 block 80;
 
System altered.

数据块dump信息:

Block header dump:  0x0140c70f
 Object id on Block? Y
 seg/obj: 0xe46c  csc: 0x00.a4a39eda  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x140c709 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000f.006.00000a14  0x02c00050.0376.10  ----    1  fsc 0x0000.00000000
0x02   0x0012.02a.0000096d  0x02c00088.0355.09  C---    0  scn 0x0000.a4a39bd8

回滚块信息:

********************************************************************************
UNDO BLK:  
xid: 0x000f.006.00000a14  seq: 0x376 cnt: 0x10  irb: 0x10  icl: 0x0   flg: 0x0000
 
 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f68     0x02 0x1ed0     0x03 0x1e50     0x04 0x1d94     0x05 0x1d2c     
0x06 0x1cd4     0x07 0x1c7c     0x08 0x1c24     0x09 0x1ba4     0x0a 0x1b24     
0x0b 0x1a8c     0x0c 0x1a0c     0x0d 0x1998     0x0e 0x1918     0x0f 0x187c     
0x10 0x17e8     
... ...
*-----------------------------
* Rec #0x10  slt: 0x06  objn: 58476(0x0000e46c)  objd: 58476  tblspc: 5(0x00000005)
*       Layer:  11 (Row)   opc: 1   rci 0x00   
Undo type:  Regular undo    Begin trans    Last buffer split:  No 
Temp Object:  No 
Tablespace Undo:  No 
rdba: 0x00000000
*-----------------------------
uba: 0x02c00050.0376.0f ctl max scn: 0x0000.a4a39a02 prv tx scn: 0x0000.a4a39a16
txn start scn: scn: 0x0000.a4a39eda logon user: 35
 prev brb: 46137423 prev bcl: 0
KDO undo record:
KTB Redo 
op: 0x04  ver: 0x01  
op: L  itl: xid:  0x0014.022.00000776 uba: 0x02c000a5.029b.32
                      flg: C---    lkc:  0     scn: 0x0000.a4a39a3e
KDO Op code: URP row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x0140c70f  hdba: 0x0140c70b
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 8
ncol: 2 nnew: 1 size: 0
Vector content: 
col  1: [ 3]  c2 02 10
 
End dump data blocks tsn: 11 file#: 11 minblk 80 maxblk 80

仔细比较一下两个dump文件,数据块的事务回滚信息就很清楚了:

在数据块中:

对象号是0xe46c,即十进制的58476

Xid0x000f.006.00000a14

Uba0x02c00050.0376.10。即11号文件的第80个数据块,回滚序列号是0x0376,回滚记录号是0x10

回滚数据块中:

Xid0x000f.006.00000a14,与数据块中Itl中的Xid对应;

seq: 0x376,与数据块的Uba中吻合;

cnt: 0x10,此回滚数据块中有16条回滚记录,根据Uba,我们要找的是第16条记录;

找到第16条回滚记录Rec #0x10

slt: 0x06,即第6slot

objnobjd58476,与数据块中的对象号相同;

tblspc5,也就是对象t_multiver所在的表空间号;

Layer即层次,这是一次对记录的更新,所以是11 (Row)

Undo type: Regular undo Begin trans,我们这个事务是刚开始时,在没有提交或回滚时dump出来的;

Temp Object: No,这个对象不是临时对象。

*-----------------------------以下的就是记录的旧数据镜像了:记录了它的Uba、最大控制Scnctl max scn)、上一次事务scnprv tx scn)等信息,如果我们做了事务开始前的数据dump,就能一一找到对应关系了。最下面就是修改前的数据记录了。

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/11423276/viewspace-988359/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-03-31

  • 博文量
    53
  • 访问量
    381914