ORACLE事物一致性的内部原理探究

       修改的数据没有提交之前,其他会话是看不到被修改的数据,被修改之前的数据会存放在UNDO里面,那么ORACLE是通过什么的方式找到存放在UNDO里面的数据呢?下面通过具体例子来说明

      首先开启两个会话,其中第一个会话只更新数据(分两种情况,一、只更新一次, 二、连续更新多次)。第二个会话查询会话一更新的数据,查看是否能查到。

1、----创建测试表并插入数据-----

SQL> create table my_test(id int, name varchar2(20));

Table created.

SQL> insert into my_test values (1,'a');

1 row created.

SQL> commit;

Commit complete.

SQL> 

会话1更新数据不提交
SQL> 
SQL> update my_test set id = 2 ;          

1 row updated.

SQL> @pid

       SID    SERIAL#        PID SPID
---------- ---------- ---------- ------------------------
       125          5         19 26271

SQL> select * from my_test;

        ID NAME
---------- --------------------
         2 a

SQL> 

2、会话2查询my_test表的数据

SQL> @pid

       SID    SERIAL#        PID SPID
---------- ---------- ---------- ------------------------
       150         15         31 26455

SQL> select * from my_test;

        ID NAME
---------- --------------------
         1 a

SQL> 

可以看到会话2(sid = 150)查看到的ID=1, 会话1(sid = 125)已经把ID更新为2,但是并没有提交。所以会话2看到ID还是更新之前的数据。ORACLE是通过UNDO的机制,把更新之后的数据写入UNDO。那么会话2是怎么通过UNDO找到会话1更新之前的数据呢?

3、查找会话1产生的UNDO数据有两种方式,由于我这是测试库,库中只有会话1更新了my_test表没有提交,不存在其他未提交事务。

  3.1、直接通过UNDO的相关视图查找会话1的产生的UNDO数据。

SQL> select addr, XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBASQN,UBAREC from v$transaction;

ADDR                 XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
000000007CB381A8         26         30      12516         19        134       1661          6

SQL> 

其中
XIDUSN  回滚段号
XIDSLOT 槽号
XIDSQN  覆盖次数
UBAFIL  回滚文件号
UBABLK  回滚块号
UBAREC  代表REC记录号


首先通过UNDO的文件号和块号查看UNDO的数据

SQL> alter system dump datafile 19 block 134;

System altered.

SQL> col VALUE for a60
SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_26545.trc

SQL> 


Block dump from disk:
buffer tsn: 11 rdba: 0x04c00086 (19/134)       <====19号文件134块
scn: 0x0000.027f8d4f seq: 0x01 flg: 0x04 tail: 0x8d4f0201
frmt: 0x02 chkval: 0x7538 type: 0x02=KTU UNDO BLOCK  <=====块类型是UNDO
Hex dump of block: st=0, typ_found=1

********************************************************************************
UNDO BLK:
xid: 0x001a.01e.000030e4  seq: 0x67d cnt: 0x6   irb: 0x6   icl: 0x0   flg: 0x0000

 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f40     0x02 0x1e98     0x03 0x1de0     0x04 0x1d38     0x05 0x1c90
0x06 0x1bf0

其中
xid 0x001a.01e.000030e4分为三个部分,第一部分代表XIDUSN=0x001a转换成10进制为26。
第二部分代表XIDSLOT=01e转换成10进制为30, 第三部分为XIDSQN=30e4转换成10进制为12516
可以看到这三个部分和v$transaction查看到的回滚段信息是一致的。
seq 对应v$transaction里面的UBASQN,0x67d转换成10进制为1661
irb代表该undo块上面最新的事务记录号0x6和v$transaction里面的UBAREC=6对应。

查看rec# = 0x6的undo数据
*-----------------------------
* Rec #0x6  slt: 0x1e  objn: 136312(0x00021478)  objd: 136312  tblspc: 0(0x00000000)
*       Layer:  11 (Row)   opc: 1   rci 0x00                        <======rci=0x00代表上面没有更新的回滚数据
Undo type:  Regular undo    Begin trans    Last buffer split:  No          (因为会话1只更新了一次)
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000Ext idx: 0
flg2: 0
*-----------------------------
uba: 0x04c00085.067d.30 ctl max scn: 0x0000.027f8ac6 prv tx scn: 0x0000.027f8acf
txn start scn: scn: 0x0000.027f8d4f logon user: 0
 prev brb: 79691908 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03  ver: 0x01
compat bit: 4 (post-11) padding: 1
op: Z
KDO Op code: URP row dependencies Disabled       <======URP 代表更新数据
  xtype: XA flags: 0x00000000  bdba: 0x00420bb9  hdba: 0x00420bb8
itli: 2  ispac: 0  maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 0
ncol: 2 nnew: 1 size: 0
col  0: [ 2]  c1 02                              <======更新之前的数据为 c102

End dump data blocks tsn: 11 file#: 19 minblk 134 maxblk 134

通过Rec #0x6上面的数据可以看到该UNDO块上面的保存的数据为c102,把c102转换成10进制如下

SQL> select utl_raw.cast_to_number('c102') from dual;

UTL_RAW.CAST_TO_NUMBER('C102')
------------------------------
                             1

SQL> 


可以看到undo块上面保存的是会话1更新之前的数据。上面是通过v$transaction视图中的UBAFIL、UBABLK确定的文件号和块号,然后再通过dump该文件号和块号得到了会话1更新之前的数据。同样也可以通过v$transaction中的XIDUSN、XIDSLOT、XIDSQN确定回滚块的信息

通过v$transaction视图查看到XIDUSN=26,代表着回滚段为26号,把XIDUSN=26的回滚段dump出来

SQL> select usn,name from v$rollname where usn = 26;

       USN NAME
---------- ------------------------------
        26 _SYSSMU26_2510430623$

SQL> 
SQL> alter system dump undo header "_SYSSMU26_2510430623$";

System altered.

SQL> 
SQL> col VALUE for a60
SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_26698.trc

SQL> 


查看/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_26698.trc内容
********************************************************************************
Undo Segment:  _SYSSMU26_2510430623$ (26)
********************************************************************************
  Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 3      #blocks: 143
                  last map  0x00000000  #maps: 0      offset: 4080
      Highwater::  0x04c00086  ext#: 2      blk#: 6      ext size: 128
  #blocks in seg. hdr's freelists: 0
  #blocks below: 0
  mapblk  0x00000000  offset: 2
                   Unlocked
     Map Header:: next  0x00000000  #extents: 3    obj#: 0      flag: 0x40000000
  Extent Map
  -----------------------------------------------------------------
   0x028000f1  length: 7
   0x028000f8  length: 8
   0x04c00080  length: 128


  TRN TBL::

  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x30e0  0x0006  0x0000.027f8c6c  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x01    9    0x00  0x30e6  0x001d  0x0000.027f8cf0  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x02    9    0x00  0x30df  0x001a  0x0000.027f8c06  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x03    9    0x00  0x30eb  0x001b  0x0000.027f8c1c  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x04    9    0x00  0x30e3  0xffff  0x0000.027f8d3b  0x04c00086  0x0000.000.00000000  0x00000002   0x00000000  1582741174
   0x05    9    0x00  0x30e5  0x0021  0x0000.027f8b5d  0x04c00081  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x06    9    0x00  0x30e5  0x0017  0x0000.027f8c7b  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x07    9    0x00  0x30e5  0x0005  0x0000.027f8b4c  0x04c00081  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x08    9    0x00  0x30e7  0x0011  0x0000.027f8c9c  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x09    9    0x00  0x30e1  0x0001  0x0000.027f8ccf  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x0a    9    0x00  0x30e7  0x0016  0x0000.027f8b1b  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x0b    9    0x00  0x30ea  0x000a  0x0000.027f8b05  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x0c    9    0x00  0x30e5  0x000d  0x0000.027f8be4  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x0d    9    0x00  0x30ed  0x000e  0x0000.027f8bf2  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x0e    9    0x00  0x30df  0x0002  0x0000.027f8bfa  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x0f    9    0x00  0x30e7  0x0012  0x0000.027f8b86  0x04c00081  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x10    9    0x00  0x30e4  0x001f  0x0000.027f8af0  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x11    9    0x00  0x30e6  0x0009  0x0000.027f8ca4  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x12    9    0x00  0x30e3  0x0014  0x0000.027f8b93  0x04c00085  0x0000.000.00000000  0x00000002   0x00000000  1582741174
   0x13    9    0x00  0x30e7  0x001c  0x0000.027f8c47  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x14    9    0x00  0x30e4  0x0018  0x0000.027f8ba4  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x15    9    0x00  0x30e2  0x0010  0x0000.027f8ae4  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x16    9    0x00  0x30e7  0x0019  0x0000.027f8b33  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x17    9    0x00  0x30e3  0x0008  0x0000.027f8c8c  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x18    9    0x00  0x30e7  0x000c  0x0000.027f8bbf  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x19    9    0x00  0x30eb  0x0007  0x0000.027f8b46  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x1a    9    0x00  0x30ea  0x0003  0x0000.027f8c0f  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x1b    9    0x00  0x30dc  0x0020  0x0000.027f8c2e  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x1c    9    0x00  0x30e7  0x0000  0x0000.027f8c5a  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x1d    9    0x00  0x30e2  0x0004  0x0000.027f8d16  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
==>0x1e   10    0x80  0x30e4  0x0002  0x0000.027f8d4f  0x04c00086  0x0000.000.00000000  0x00000001   0x00000000  0
   0x1f    9    0x00  0x30e7  0x000b  0x0000.027f8af8  0x04c00084  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x20    9    0x00  0x30e3  0x0013  0x0000.027f8c40  0x04c00085  0x0000.000.00000000  0x00000001   0x00000000  1582741174
   0x21    9    0x00  0x30de  0x000f  0x0000.027f8b65  0x04c00081  0x0000.000.00000000  0x00000001   0x00000000  1582741174

查看回滚段的RN TBL::信息,发现index=0x1e这行的state=10,10代表是活动事物。dba(data block address)为0x04c00086,意思就是该事物对应的undo数据在0x4c00086上面。把0x4c00086转换成文件号和块号,如下:

SQL> select to_number('4c00086','xxxxxxxx') from dual;

TO_NUMBER('4C00086','XXXXXXXX')
-------------------------------
                       79691910

SQL> select dbms_utility.data_block_address_file(79691910) from dual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(79691910)
----------------------------------------------
                                            19

SQL>  select dbms_utility.data_block_address_block(79691910) from dual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(79691910)
-----------------------------------------------
                                            134

SQL> 

可以看到dba转换成10文件号和块号之后正是v$transaction中的DBAFIL、DBABLK。找到undo的文件号和块号之后就可以
按照上面的方法找到undo块上面对应的会话1更新前的数据

wrap#=0x30e3代表v$transaction里面的XIDSQN,转换成10进制为12515。

3.2  方法一是直接通过v$transaction视图里面的数据来查找会话1更新之前的undo数据。但是会话2查询my_test数据时不会通过  v$transaction里面去查找undo数据。会话2也不会知道v$transaction里面哪行数据对应my_test表的前镜像。

会话2查询数据的过程如下:
查询my_test表时,首先找到my_test表对应的数据块

SQL>   select dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) from my_test;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                   1                               134073

SQL> 

因为会话1更新了1号文件134073的块,所以块上面会有事物信息,查看上面事物信息

SQL> 
SQL> alter system dump datafile 1 block 134073;

System altered.

SQL> select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_26859.trc

SQL> 

查看/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_26859.trc内容
Block dump from disk:
buffer tsn: 0 rdba: 0x00420bb9 (1/134073)
scn: 0x0000.027f8d66 seq: 0x01 flg: 0x04 tail: 0x8d660601
frmt: 0x02 chkval: 0xa68e type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007FA900615A00 to 0x00007FA900617A00


7FA9006179F0 00000000 0202022C 610103C1 8D660601  [....,......a..f.]
Block header dump:  0x00420bb9
 Object id on Block? Y
 seg/obj: 0x21478  csc: 0x00.27f8d66  itc: 2  flg: O  typ: 1 - DATA  
     fsl: 0  fnx: 0x0 ver: 0x01

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x001a.000.000030df  0x04c00084.067d.03  C---    0  scn 0x0000.027f8a36
0x02   0x001a.01e.000030e4  0x04c00086.067d.06  ----    1  fsc 0x0000.00000000

可以看到Itl =0x02上面的Lck=1。说明该块上面有其他会话修改,并且没有提交。会话2访问该块的时候只能通过UBA(undo block address)的UNDO数据找到旧镜像。其中Xid =0x001a.01e.000030e4就是对应v$transaction的XIDUSN、XIDSLOT、XIDSQN。转换成10进制分别为第一部分代表XIDUSN=0x001a转换成10进制为26。第二部分代表XIDSLOT=01e转换成10进制为30, 第三部分为XIDSQN=30e4转换成10进制为12516。和v$transaction里面看到的一样UBA的数据为0x04c00086.067d.06其中第一部分为undo块的地址,转为文件号和块号如下:

SQL> select to_number('4c00086','xxxxxxxx') from dual;

TO_NUMBER('4C00086','XXXXXXXX')
-------------------------------
                       79691910

SQL> select dbms_utility.data_block_address_file(79691910) from dual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(79691910)
----------------------------------------------
                                            19

SQL>  select dbms_utility.data_block_address_block(79691910) from dual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(79691910)
-----------------------------------------------
                                            134

SQL> 


第二部分为UBASQN=067d转换成10进制为 1661。
第三部分为UBAREC=6进制也为6。 
可以看到数据块上面对应的事务信息和v$transaction里面查到的数据完全一致,然后再按照方法一的方式找到UNDO上面的数据。

所以会话2查看my_test表内容时发现数据块上面存在事物信息, 然后根据事物的xid以及uba信息找到保存着undo块上面的数据,然后再和没有修改的列组成查询返回的数据。就得到的如下数据

SQL> select * from my_test;

        ID NAME
---------- --------------------
         1 a

SQL>   

4、还有文章开头提到的如果会话1连续更新多次,UNDO上面的数据是怎么保存的呢?


SQL> update my_test set id = 3;

1 row updated.

SQL> update my_test set id = 4;

1 row updated.

SQL> update my_test set id = 5;

1 row updated.

SQL> @pid

       SID    SERIAL#        PID SPID
---------- ---------- ---------- ------------------------
       125          5         19 26271

SQL>

会话1又更新了3次没有提交。然后再次dump数据块

SQL> alter system dump datafile 1 block 134073;

System altered.

SQL>


查看dump文件的事务信息如下:
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x001a.000.000030df  0x04c00084.067d.03  C---    0  scn 0x0000.027f8a36
0x02   0x001a.01e.000030e4  0x04c00086.067d.09  ----    1  fsc 0x0000.00000000
bdba: 0x00420bb9
data_block_dump,data header at 0x7fa900615a5c
===============
tsiz: 0x1fa0
hsiz: 0x14
pbl: 0x7fa900615a5c
     76543210

和第一次dump的对比
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x001a.000.000030df  0x04c00084.067d.03  C---    0  scn 0x0000.027f8a36
0x02   0x001a.01e.000030e4  0x04c00086.067d.06  ----    1  fsc 0x0000.00000000

可以看到xid的数据是一致的,uba中的前两个部分也是一致的,只有第三个部分UBASQN发生了变化,由原来的6变成了9。
Uba的第一部分并没有发生变化,所有UNDO对应的文件号和块号是没有发生变化的。再次dump undo块查看内容

SQL> alter system dump datafile 19 block 134;

System altered.

SQL>  select value from v$diag_info where name = 'Default Trace File';

VALUE
--------------------------------------------------------------------------------
/u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_29036.trc

SQL> 

查看UNDO BLK信息
UNDO BLK:
xid: 0x001a.01e.000030e4  seq: 0x67d cnt: 0x9   irb: 0x9   icl: 0x0   flg: 0x0000

 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f40     0x02 0x1e98     0x03 0x1de0     0x04 0x1d38     0x05 0x1c90
0x06 0x1bf0     0x07 0x1b7c     0x08 0x1b08     0x09 0x1a94

*-----------------------------
和第一次dump的对比
UNDO BLK:
xid: 0x001a.01e.000030e4  seq: 0x67d cnt: 0x6   irb: 0x6   icl: 0x0   flg: 0x0000

 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f40     0x02 0x1e98     0x03 0x1de0     0x04 0x1d38     0x05 0x1c90
0x06 0x1bf0

可以发现变为的为Rec有原来的最大0x06变成了现在的0x09,和Uba的变化正好相对应。

查看Rec=9的UNDO内容

*-----------------------------
* Rec #0x9  slt: 0x1e  objn: 136312(0x00021478)  objd: 136312  tblspc: 0(0x00000000)
*       Layer:  11 (Row)   opc: 1   rci 0x08    <=====指向上一个指针
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
compat bit: 4 (post-11) padding: 1
op: C  uba: 0x04c00086.067d.08
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x00420bb9  hdba: 0x00420bb8
itli: 2  ispac: 0  maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 2 ckix: 0
ncol: 2 nnew: 1 size: 0
col  0: [ 2]  c1 05    <====转换成10进制为4

SQL> select utl_raw.cast_to_number('c105') from dual;

UTL_RAW.CAST_TO_NUMBER('C105')
------------------------------
                             4

SQL>

rci=0x08 代表指向上一个指针。查看Rec=8 的内容

* Rec #0x8  slt: 0x1e  objn: 136312(0x00021478)  objd: 136312  tblspc: 0(0x00000000)
*       Layer:  11 (Row)   opc: 1   rci 0x07    <=====指向上一个指针
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
compat bit: 4 (post-11) padding: 1
op: C  uba: 0x04c00086.067d.07
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x00420bb9  hdba: 0x00420bb8
itli: 2  ispac: 0  maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 2 ckix: 0
ncol: 2 nnew: 1 size: 0
col  0: [ 2]  c1 04   <====转换成10进制为3

rci=0x07 代表指向上一个指针。查看Rec=7 的内容

*-----------------------------
* Rec #0x7  slt: 0x1e  objn: 136312(0x00021478)  objd: 136312  tblspc: 0(0x00000000)
*       Layer:  11 (Row)   opc: 1   rci 0x06    <=====指向上一个指针
Undo type:  Regular undo   Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
compat bit: 4 (post-11) padding: 1
op: C  uba: 0x04c00086.067d.06
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x00420bb9  hdba: 0x00420bb8
itli: 2  ispac: 0  maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 2 ckix: 0
ncol: 2 nnew: 1 size: 0
col  0: [ 2]  c1 03  <====转换成10进制为2

rci=0x06 代表指向上一个指针。查看Rec=6 的内容

*-----------------------------
* Rec #0x6  slt: 0x1e  objn: 136312(0x00021478)  objd: 136312  tblspc: 0(0x00000000)
*       Layer:  11 (Row)   opc: 1   rci 0x00      <=====上一个指针为NULL
Undo type:  Regular undo    Begin trans    Last buffer split:  No
Temp Object:  No
Tablespace Undo:  No
rdba: 0x00000000Ext idx: 0
flg2: 0
*-----------------------------
uba: 0x04c00085.067d.30 ctl max scn: 0x0000.027f8ac6 prv tx scn: 0x0000.027f8acf
txn start scn: scn: 0x0000.027f8d4f logon user: 0
 prev brb: 79691908 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03  ver: 0x01
compat bit: 4 (post-11) padding: 1
op: Z
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x00420bb9  hdba: 0x00420bb8
itli: 2  ispac: 0  maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 0
ncol: 2 nnew: 1 size: 0 
col  0: [ 2]  c1 02     <====转换成10进制为1

rci=0x00 意味着Rec=6就是UNDO上面最原始的数据了,该数据内容为c102转换成10进制为1,这个1也正是会话1第一次更新的数据。
        所以,一个会话如果有多次更新没有提交,那么它会在undo里面存在多份更新之后的数据,这些数据通过指针的方式串联起来,如果其他会话需要使用undo数据的时候就要根据指针找到链表头即为需要的UNDO数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值