Oracle的undo是block的全鏡像嗎?實際保存哪些信息?

概述

undo保存修改數據的前鏡像,用來回滾或者一致性讀。
那麼undo裏存的具體內容是什麼?是block的全鏡像嗎?

解答這個問題,需要知道:

  1. update的內部過程
  2. oracle中事務的關鍵信息
  3. 如何定位事務對應的undo block
  4. 如何查看undo block的信息

1)update的過程

  1. 事務表登記1條事務記錄
  2. 向undo block中保存舊值
  3. 修改data block,保存新值
  4. 其他信息。

2)oracle中事務的關鍵信息

可通過v$transaction的字段瞭解。
關鍵信息包括:
ADDR事物狀態地址、 id、UBAFIL+UBABLK undo block地址、STATUS 狀態、IO統計信息等

    Column   Datatype   Description
    ADDR   RAW(4 | 8)   Address of the transaction state object
    XIDUSN   NUMBER   Undo segment number
    XIDSLOT   NUMBER   Slot number
    XIDSQN   NUMBER   Sequence number
    UBAFIL   NUMBER   Undo block address (UBA) filenum
    UBABLK   NUMBER   UBA block number
    UBASQN 	NUMBER 	UBA sequence number
    UBAREC 	NUMBER 	UBA record number
    STATUS 	VARCHAR2(16) 	Status
    START_TIME 	VARCHAR2(20) 	Start time (wall clock)
    START_SCNB 	NUMBER 	Start system change number (SCN) base
    START_SCNW 	NUMBER 	Start SCN wrap
    START_UEXT 	NUMBER 	Start extent number
    START_UBAFIL 	NUMBER 	Start UBA file number
    START_UBABLK 	NUMBER 	Start UBA block number
    START_UBASQN 	NUMBER 	Start UBA sequence number
    START_UBAREC 	NUMBER 	Start UBA record number
    SES_ADDR 	RAW(4 | 8) 	User session object address
    FLAG 	NUMBER 	Flag
    SPACE 	VARCHAR2(3) 	YES if a space transaction
    RECURSIVE 	VARCHAR2(3) 	YES if a recursive transaction
    NOUNDO 	VARCHAR2(3) 	YES if a no undo transaction
    PTX 	VARCHAR 2(3) 	YES if parallel transaction
    NAME 	VARCHAR2(256) 	Name of a named transaction
    PRV_XIDUSN 	NUMBER 	Previous transaction undo segment number
    PRV_XIDSLT 	NUMBER 	Previous transaction slot number
    PRV_XIDSQN 	NUMBER 	Previous transaction sequence number
    PTX_XIDUSN 	NUMBER 	Rollback segment number of the parent XID
    PTX_XIDSLT 	NUMBER 	Slot number of the parent XID
    PTX_XIDSQN 	NUMBER 	Sequence number of the parent XID
    DSCN-B 	NUMBER 	This column is obsolete and maintained for backward compatibility. The value of this column is always equal to the value in DSCN_BASE.
    DSCN-W 	NUMBER 	This column is obsolete and maintained for backward compatibility. The value of this column is always equal to the value in DSCN_WRAP.
    USED_UBLK 	NUMBER 	Number of undo blocks used
    USED_UREC 	NUMBER 	Number of undo records used
    LOG_IO 	NUMBER 	Logical I/O
    PHY_IO 	NUMBER 	Physical I/O
    CR_GET 	NUMBER 	Consistent gets
    CR_CHANGE 	NUMBER 	Consistent changes
    START_DATE 	DATE 	Start time (wall clock)
    DSCN_BASE 	NUMBER 	Dependent SCN base
    DSCN_WRAP 	NUMBER 	Dependent SCN wrap
    START_SCN 	NUMBER 	Start SCN
    DEPENDENT_SCN 	NUMBER 	Dependent SCN
    XID 	RAW(8) 	Transaction XID
    PRV_XID 	RAW(8) 	Previous transaction XID
    PTX_XID 	RAW(8) 	Parent transaction XID

3) 如何定位事務對應的undo block

2個方法:

法1:

通過 v$transaction,可用v$session查找事物address。

--查詢本會話id,sid 132
 select * from v$mystat;  
 
--根據會話id,查看事物狀態地址:000007FF7ACE7A88    
 select * from v$session  s where s.SID=132; 
 
--查看事務信息    
 select * from v$transaction t where t.ADDR='000007FF7ACE7A88';

法2:

通過data block中的itl信息。
根據修改記錄的rowid,找到fileno,blockno;dump block內容。

4)如何查看undo block的信息

--dump數據塊信息
    alter system dump datafile 13 block 4996;

查看dump文件路徑,注意路徑一致,但文件不一定完全一致。可根據文件的更新時間判斷。

    select * from v$diag_info t where t.NAME = 'Default Trace File';

設計實驗

實驗步驟

1.更新多條記錄不提交
2.從mystat查詢當前sessionid
3.根據sessionid從transaction表查詢xid、uba
4.dump datablock,從itl中看uba與事務表是否一致
5.dump undo block,查看其中的內容

具體過程:

1.更新多條記錄不提交

當前數據

DEPT_NO SAL EMP_NO PADDING
2 20200513153556 5000
3 9999 5001
4 9999 5002

創建事務:更新但不提交。

  update EMP t set t.sal = 9999 where t.emp_no in (5000, 5001, 5002);

2.從事物表查詢對應的undoBlock

  select tr.*,s.SID,s.SERIAL#
  from (select * from v$mystat where rownum = 1) stat,
       v$session s,
       v$transaction tr
 where stat.sid = s.SID
   and s.TADDR = tr.ADDR ;
   
ADDR XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
000007FF7AD348B0 9 3 269771 3 934 27824 6

本事務的 undo block 在 undofile 3,block sn 934.

3.從datablock中dump出undo block

查詢修改記錄對應rowid,轉換成fileno+blockNo

DEPT_NO SAL EMP_NO PADDING ROWID FNO BLOCKNO ROWNO
2 20 5000 x AAASQbAANAAABOEAAO 13 4996
3 20 5001 x AAASQbAANAAABOEAAP 13 4996
4 20 5002 x AAASQbAANAAABOEAAQ 13 4996

dump data block

alter system dump datafile 13 block 4996;
   Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0002.004.0004303b  0x00c0854a.7119.12  ----    3  fsc 0x0000.00000000
0x02   0x0008.021.00000cf6  0x00c0008f.0a3c.0b  --U-    2  fsc 0x0060.ebd5624b

看Flag=’----'的,標示事務還沒提交,就這實驗的事務。
解析Uba的信息

  select dbms_utility.data_block_address_file(to_number('c0854a',
                                                      'xxxxxxxxxxxx')) file#,
       dbms_utility.data_block_address_block(to_number('c0854a',
                                                       'xxxxxxxxxxxx')) block#
  from dual;

FILE# BLOCK#
3 34122
對應的undo一致。
ps:後來整理筆記的時候,原來的日誌覆蓋了,這裏實際不一致。見諒,意在說明意思。。

4.dump undo block信息,查看

--dump數據塊信息
    alter system dump datafile 3 block 934;

查看dump出的trace文件內容:

*-----------------------------
* Rec #0x4  slt: 0x03  objn: 74779(0x0001241b)  objd: 74779  tblspc: 9(0x00000009)
*       Layer:  11 (Row)   opc: 1   rci 0x00   
Undo type:  Regular undo    Begin trans    Last buffer split:  No 
Temp Object:  No 
Tablespace Undo:  No 
rdba: 0x00000000Ext idx: 0
flg2: 0
*-----------------------------
uba: 0x00c003a6.6cb0.02 ctl max scn: 0x0f00.94c4621b prv tx scn: 0x0f00.94c46237
txn start scn: scn: 0x0f00.94c464f1 logon user: 93
 prev brb: 12583845 prev bcl: 0
KDO undo record:
KTB Redo 
op: 0x04  ver: 0x01  
compat bit: 4 (post-11) padding: 0
op: L  itl: xid:  0x0008.00c.00043465 uba: 0x00c01e79.78af.0d
                      flg: C---    lkc:  0     scn: 0x0f00.94c3a499
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x03401384  hdba: 0x03401383
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 14(0xe) flag: 0x2c lock: 0 ckix: 0
ncol: 4 nnew: 1 size: 6
col  1: [ 8]  c7 15 15 06 0e 10 24 39
 
*-----------------------------
* Rec #0x5  slt: 0x03  objn: 74779(0x0001241b)  objd: 74779  tblspc: 9(0x00000009)
*       Layer:  11 (Row)   opc: 1   rci 0x04   
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: 0
op: C  uba: 0x00c003a6.6cb0.04
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x03401384  hdba: 0x03401383
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 15(0xf) flag: 0x2c lock: 0 ckix: 0
ncol: 4 nnew: 1 size: 1
col  1: [ 3]  c2 64 64
 
*-----------------------------
* Rec #0x6  slt: 0x03  objn: 74779(0x0001241b)  objd: 74779  tblspc: 9(0x00000009)
*       Layer:  11 (Row)   opc: 1   rci 0x05   
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: 0
op: C  uba: 0x00c003a6.6cb0.05
KDO Op code: URP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x03401384  hdba: 0x03401383
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 16(0x10) flag: 0x2c lock: 0 ckix: 0
ncol: 4 nnew: 1 size: 1
col  1: [ 3]  c2 64 64

值轉換

  select UTL_RAW.CAST_TO_NUMBER(replace('c7 15 15 06 0e 10 24 39', ' ')) SAL_old1,
       UTL_RAW.CAST_TO_NUMBER(replace('c2 64 64  ', ' ')) SAL_old2,
       UTL_RAW.CAST_TO_NUMBER(replace('c2 64 64  ', ' ')) SAL_old3
  from dual;

解析:與字段舊值一致。

SAL_OLD1 SAL_OLD2 SAL_OLD3
20200513153556 9999 9999

總結

綜上
1.undo block是保存的數據前鏡像,但不是整block的前鏡像。
2.前鏡像只保存所修改字段的舊值。
3.rowid是是非常重要的定位信息,file、block、rownum定義一條記錄。
4.事務是修改數據的,一個重要屬性就是關聯的undo block。

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