UNDO

本文详细解析了Oracle数据库中如何通过回滚段保留事务的前镜像信息,包括使用SQL命令创建测试表、更新数据块记录,以及利用系统命令dump出数据块和回滚段信息等关键步骤。

步骤一、先准备测试表
SQL> create table test as select * from dba_objects;
表已创建。


步骤二、分别更新两个数据块的三条记录,每更新一条提交一次。目的是为了在数据块的itl slot中插入几条记录。可以通过包dbms_rowid来获得数据块信息。
SQL>select dbms_rowid.ROWID_RELATIVE_FNO(rowid) fn, dbms_rowid.rowid_block_number(rowid) bl, test.object_id from test where rownum<200;
FN         BL  OBJECT_ID
--- ---------- ----------
4       1012         32
4       1012         22
4       1012         49
4       1012         30

 

FN         BL  OBJECT_ID
--- ---------- ----------
 4       1013        119
 4       1013        120
 4       1013        121
 4       1013        122
SQL> update test set object_id=3 where object_id=32;
已更新 1 行。
SQL> commit;
提交完成。


其余省略

注意这两个数据块的第四个记录暂不更新,只更新每个数据块的前三条记录,并且每更新一条,提交一次(有点墨迹啊。。)。

 

步骤三、dump出这两个数据块的内容,保存itl信息为后续步骤服务。

SQL> alter system dump datafile 4 block 1012;

系统已更改。

SQL> alter system dump datafile 4 block 1013;

系统已更改。

 

数据块1012的itl信息。

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0001.025.0000015d  0x008009cf.00bf.03  --U-    1  fsc 0x0000.000ca086
0x02   0x0004.01a.00000149  0x008000e5.0121.06  --U-    1  fsc 0x0000.000ca081

数据块1013的itl信息。

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x000a.021.00000148  0x00800153.00cb.04  --U-    1  fsc 0x0001.000ca091
0x02   0x0003.012.00000156  0x008000ce.0129.06  --U-    1  fsc 0x0001.000ca08d

 

步骤四、一个事务里更新两个数据块的第四条记录,不提交。

SQL> update test set object_id=3 where object_id=30;

已更新 1 行。

SQL> update test set object_id=3 where object_id=122;

已更新 1 行。

 

步骤五、查看v$transaction视图,获得事务信息。

SQL> select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec from v$transaction;

    XIDUSN    XIDSLOT     XIDSQN     UBABLK     UBAFIL     UBAREC
---------- ---------- ---------- ---------- ---------- ----------
         6         45        346        980          2         31

可以看出占用的是6号回滚段,45号事务槽。占用的回滚块是2号文件,980号块。

 

步骤六、把回滚段头和回滚块dump出来。仅列出重点内容。部分内容省略。

SQL> alter system dump undo header '_SYSSMU6$';

系统已更改。

SQL> alter system dump datafile 2 block 980;

系统已更改。

回滚段头的dump内容:

********************************************************************************
Undo Segment:  _SYSSMU6$ (6)
********************************************************************************
  Extent Control Header
  -----------------------------------------------------------------
  
  TRN CTL:: seq: 0x0134 chd: 0x0020 ctl: 0x002e inc: 0x00000000 nfb: 0x0000
            mgc: 0x8201 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
            uba: 0x008003d4.0134.1e scn: 0x0000.000c99cf
  TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x015b  0x002e  0x0000.000ca098  0x008003d4  0x0000.000.00000000  0x00000001   0x00000000  1289970123
   0x2d   10    0x80  0x015a  0x0002  0x0000.000ca091  0x008003d4  0x0000.000.00000000  0x00000001   0x00000000  0

index列代表事务槽号,state列,9代表没有活动事务,10代表活动事务。dba代表占用undo块地址。从上面可以看出45号(0x2d)事务槽上有活动事务,跟v$transaction中的信息一致。0x2d转换为十进制是45,0x008003d4  转换为2号文件 980块。转换函数如下:

CREATE OR REPLACE FUNCTION getbfno (p_dba IN VARCHAR2)
   RETURN VARCHAR2
IS
   l_str   VARCHAR2 (255) DEFAULT NULL;
BEGIN
   l_str :=
         'datafile# is:'
      || DBMS_UTILITY.data_block_address_file (TO_NUMBER (LTRIM (p_dba, '0x'),'xxxxxxxx'))
      || chr(10)||'datablock is:'
      || DBMS_UTILITY.data_block_address_block (TO_NUMBER (LTRIM (p_dba, '0x'),'xxxxxxxx'));
   RETURN l_str;
END;
/
SQL> select getbfno('0x008003d4') from dual;

GETBFNO('0X008003D4')
--------------------------------------------------
datafile# is:2
datablock is:980

 

回滚块dump的内容:

********************************************************************************
UNDO BLK: 
xid: 0x0006.02d.0000015a  seq: 0x134 cnt: 0x1f  irb: 0x1f  icl: 0x0   flg: 0x0000
 
 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f4c     0x02 0x1ea4     0x03 0x1e00     0x04 0x1d80     0x05 0x1cf8    
0x06 0x1c18     0x07 0x1bb4     0x08 0x1b60     0x09 0x1a80     0x0a 0x1a1c    
0x0b 0x19c8     0x0c 0x18f8     0x0d 0x1878     0x0e 0x17f8     0x0f 0x1760    
0x10 0x1710     0x11 0x1690     0x12 0x160c     0x13 0x158c     0x14 0x14bc    
0x15 0x13dc     0x16 0x1378     0x17 0x1324     0x18 0x12a0     0x19 0x123c    
0x1a 0x118c     0x1b 0x110c     0x1c 0x1084     0x1d 0x0ff0     0x1e 0x0f40    
0x1f 0x0ed8    

*-----------------------------
* Rec #0x1e  slt: 0x2d  objn: 51447(0x0000c8f7)  objd: 51448  tblspc: 4(0x00000004)
*       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: 0x008003d4.0134.1d ctl max scn: 0x0000.000c99aa prv tx scn: 0x0000.000c99cf
txn start scn: scn: 0x0000.00000000 logon user: 54
 prev brb: 8389585 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04  ver: 0x01 
op: L  itl: xid:  0x0004.01a.00000149 uba: 0x008000e5.0121.06
                      flg: C---    lkc:  0     scn: 0x0000.000ca081

Array Update of 1 rows:
tabn: 0 slot: 42(0x2a) flag: 0x2c lock: 0 ckix: 8
ncol: 13 nnew: 1 size: 0
KDO Op code:  21 row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x010003f4  hdba: 0x010003f3
itli: 2  ispac: 0  maxfr: 4858
vect = 13
col  3: [ 2]  c1 1f
 
*-----------------------------
* Rec #0x1f  slt: 0x2d  objn: 51447(0x0000c8f7)  objd: 51448  tblspc: 4(0x00000004)
*       Layer:  11 (Row)   opc: 1   rci 0x1e  
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x04  ver: 0x01 
op: L  itl: xid:  0x0003.012.00000156 uba: 0x008000ce.0129.06
                      flg: C---    lkc:  0     scn: 0x0000.000ca08d
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x010003f5  hdba: 0x010003f3
itli: 2  ispac: 0  maxfr: 4858
tabn: 0 slot: 28(0x1c) flag: 0x2c lock: 0 ckix: 0
ncol: 13 nnew: 1 size: 1
col  3: [ 3]  c2 02 17

 

dump文件里有一个参数irb: 0x1f,irb指的是回滚段中记录的最近未提交变更开始之处,如果开始回滚,这是起始的搜索点。我们从dump文件中找到0x1f。col  3: [ 3]  c2 02 17代表的就是122,这是最后更新记录的前镜像。ORACLE就这样回滚保留前镜像信息的。这里还有个参数rci,该参数代表就是undo chain的下一个偏移量,这里为0x1e,我们再找到0x1e这条undo记录。col  3: [ 2]  c1 1f记录的就是我们的第一条更新的数据。ORACLE通过rci把这些UNDO记录串成链,直到rci为0X00代表已经达到事务的第一条记录。

 

这些op: L  itl: xid:  0x0003.012.00000156 uba: 0x008000ce.0129.06
                      flg: C---    lkc:  0     scn: 0x0000.000ca08d

代表覆盖的数据块的itl的信息。是非常重要的数据结构。

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

转载于:http://blog.itpub.net/22034023/viewspace-678324/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值