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數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章