關於UNDO 內部一致性讀和回滾依賴的UNDO CHAIN描述
首先說明一下UNDO裡面會形成一個從最後一條記錄到第一條記錄的一個反向連結串列,為什麼要這樣是因為
當我們把記錄A修改為B然後又修改為C後,我們需要先找到C的UNDO修改為B,然後找到B的UNDO修改為A
這樣才能按照順序進行回滾。
這樣的構架能夠滿足一致性讀和回滾操作。
如下我做了一個
SQL> delete test123123;
34 rows deleted
首先找到這個語句修改了那個塊或者那些塊,提取其中一個即可。
我這裡修改的是file 1的塊92025,所以我們DUMP出來看一下
alter system dump datafile 1 block 92025;
找到其中的ITL
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00233217
0x02 0x0009.020.000004f5 0x00c00d16.014b.1f ---- 35 fsc 0x0f45.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
根據這個ITL我們可以清楚看到這個事物使用了ITL 0x02,關於如何看ITL請看如下文章,關於ITL中的解釋
http://blog.itpub.net/7728585/viewspace-1709334/
這裡我們得到了TRANSACTION TABLE中的SLT位置
0x0009.020.000004f5
同時我們得到了這個事物修改的最後一個UBA的位置
0x00c00d16.014b.1f
如此我們DUMP UNDO SEGNMENT 9的UNDO HEADER,以及UBA中DBA 00c00d16進行檢視
使用DUMP命令
alter system dump datafile 3 block 3350;
alter system dump undo header '_SYSSMU9_3945653786$';
如下:
UNDO HEADER中的TRANSACTION表
TRN CTL:: seq: 0x014b chd: 0x0014 ctl: 0x0015 inc: 0x00000000 nfb: 0x0000
mgc: 0xb000 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x00c00d15.014b.36 scn: 0x0000.002686ea
.......
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
.......
0x1e 9 0x00 0x04f3 0x0017 0x0000.00268f75 0x00c00d14 0x0000.000.00000000 0x00000001 0x00000000 1429116355
0x1f 9 0x00 0x04f3 0x000a 0x0000.002694a3 0x00c00d15 0x0000.000.00000000 0x00000001 0x00000000 1429117555
0x20 10 0x80 0x04f5 0x0002 0x0000.00000000 0x00c00d16 0x0000.000.00000000 0x00000002 0x00000000 0
0x21 9 0x00 0x04f4 0x001c 0x0000.0026954d 0x00c00d15 0x0000.000.00000000 0x00000001 0x00000000 1429117555
這裡觀察SLT 0X20 這正是我們正在使用的SLT槽
這部分也可以檢視http://blog.itpub.net/7728585/viewspace-1709334/進行了解
然後檢視0x00c00d16.014b.1f所指向的UNDO,由於篇幅問題我擷取其中第一個REC和最後一個REC,及KTUBH
UNDO BLK:
xid: 0x0009.020.000004f5 seq: 0x14b cnt: 0x1f irb: 0x1f icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f04 0x02 0x1e20 0x03 0x1d28 0x04 0x1c2c 0x05 0x1bc8
0x06 0x1acc 0x07 0x19d4 0x08 0x18dc 0x09 0x17e4 0x0a 0x16e0
0x0b 0x15e8 0x0c 0x14ec 0x0d 0x13f0 0x0e 0x12f4 0x0f 0x11fc
0x10 0x1104 0x11 0x1010 0x12 0x0f18 0x13 0x0e24 0x14 0x0d28
0x15 0x0c30 0x16 0x0b2c 0x17 0x0a34 0x18 0x093c 0x19 0x0840
0x1a 0x0744 0x1b 0x064c 0x1c 0x0558 0x1d 0x0458 0x1e 0x0350
0x1f 0x0248
*-----------------------------
* Rec #0x1 slt: 0x20 objn: 76757(0x00012bd5) objd: 76757 tblspc: 0(0x00000000)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00c00d15
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: C uba: 0x00c00d15.014b.39
KDO Op code: IRP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x00416779 hdba: 0x00416778
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 4(0x4) size/delt: 101
fb: --H-FL-- lb: 0x0 cc: 15
null:
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--N-N------N---
col 0: [ 8] 54 45 53 54 44 55 4d 50
col 1: [ 2] c1 56
col 2: *NULL*
col 3: [ 4] 4f 50 45 4e
col 4: *NULL*
col 5: [ 7] 78 73 09 0a 08 0a 3b
col 6: [ 5] 55 53 45 52 53
col 7: [ 4] 54 45 4d 50
col 8: [ 7] 78 73 03 0e 08 0a 3b
col 9: [ 7] 44 45 46 41 55 4c 54
col 10: [22]
44 45 46 41 55 4c 54 5f 43 4f 4e 53 55 4d 45 52 5f 47 52 4f 55 50
col 11: *NULL*
col 12: [ 8] 31 30 47 20 31 31 47 20
col 13: [ 1] 4e
col 14: [ 8] 50 41 53 53 57 4f 52 44
.....................
*-----------------------------
* Rec #0x1f slt: 0x20 objn: 76757(0x00012bd5) objd: 76757 tblspc: 0(0x00000000)
* 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: 0x02 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: C uba: 0x00c00d16.014b.1e
KDO Op code: IRP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x00416779 hdba: 0x00416778
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 33(0x21) size/delt: 133
fb: --H-FL-- lb: 0x0 cc: 15
null:
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--N--------N---
col 0: [21]
53 50 41 54 49 41 4c 5f 57 46 53 5f 41 44 4d 49 4e 5f 55 53 52
col 1: [ 2] c1 43
col 2: *NULL*
col 3: [16] 45 58 50 49 52 45 44 20 26 20 4c 4f 43 4b 45 44
col 4: [ 7] 78 6f 09 11 0b 0a 29
col 5: [ 7] 78 6f 09 11 0b 0a 29
col 6: [ 5] 55 53 45 52 53
col 7: [ 4] 54 45 4d 50
col 8: [ 7] 78 6f 09 11 0b 0a 29
col 9: [ 7] 44 45 46 41 55 4c 54
col 10: [22]
44 45 46 41 55 4c 54 5f 43 4f 4e 53 55 4d 45 52 5f 47 52 4f 55 50
col 11: *NULL*
col 12: [ 8] 31 30 47 20 31 31 47 20
col 13: [ 1] 4e
col 14: [ 8] 50 41 53 53 57 4f 52 44
先來看看KTUBH
xid: 0x0009.020.000004f5 seq: 0x14b cnt: 0x1f irb: 0x1f icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f04 0x02 0x1e20 0x03 0x1d28 0x04 0x1c2c 0x05 0x1bc8
0x06 0x1acc 0x07 0x19d4 0x08 0x18dc 0x09 0x17e4 0x0a 0x16e0
0x0b 0x15e8 0x0c 0x14ec 0x0d 0x13f0 0x0e 0x12f4 0x0f 0x11fc
0x10 0x1104 0x11 0x1010 0x12 0x0f18 0x13 0x0e24 0x14 0x0d28
0x15 0x0c30 0x16 0x0b2c 0x17 0x0a34 0x18 0x093c 0x19 0x0840
0x1a 0x0744 0x1b 0x064c 0x1c 0x0558 0x1d 0x0458 0x1e 0x0350
0x1f 0x0248
這裡首先記錄修改這個UNDO BLOCK的 XID,一個UNDO BLOCK同時只能由一個TRANSACTION進行修改,所以可以說XID是唯一,他正是
我修改語句的事物。SEQ記錄了這個塊SEQ,這個在以前的文章中也有解釋http://blog.itpub.net/7728585/viewspace-1709334/
簡單的說每次修改都會增加1,接下來是cnt就是包含的記錄數,然後是IRB通常他指向最後一條記錄
然後看看我們的最後一條記錄 0x1f:
*-----------------------------
* Rec #0x1f slt: 0x20 objn: 76757(0x00012bd5) objd: 76757 tblspc: 0(0x00000000)
* Layer: 11 (Row) opc: 1 rci 0x1e
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
這部分我們稱為KTUBU,
rec # 不用解釋就是記錄的排序
SLT 就是我們在UNDO HEADER裡面TRANSACTION TABLE的槽號
objn:OBJECT_ID
objd:DATA_OBJECT_ID
兩者有一定的區別OBJECT_ID是不變的,DATA_OBJECT_ID是可變的每次TRUNCATE都會變動一次
rci:是一個重要的指標,他指向前一條回滾記錄,undo chain的重要組成成員
rdba:如果前一個UNDO記錄不在同一塊中指向前一個UNDO BLOCK,通常在第一條REC 出現,此時RCI為0
關於RCI和RDBA我們看一下DUMP出來的第一條記錄中的值
rci 0x00
rdba: 0x00c00d15
這裡可以看到這個塊這並不是這個事物的全部塊,他還有部分記錄在0x00c00d15中。
如此我們進行0x00c00d15塊的DUMP,在這塊中我們找到本事物的第一個UNDO REC
*-----------------------------
* Rec #0x36 slt: 0x20 objn: 76757(0x00012bd5) objd: 76757 tblspc: 0(0x00000000)
* 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: 0x00c00d15.014b.35 ctl max scn: 0x0000.002686e0 prv tx scn: 0x0000.002686ea
txn start scn: scn: 0x0000.00000000 logon user: 0
prev brb: 12586260 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: Z
KDO Op code: IRP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x00416779 hdba: 0x00416778
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 0(0x0) size/delt: 83
fb: --H-FL-- lb: 0x0 cc: 15
null:
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--N-N------N---
col 0: [ 3] 53 59 53
col 1: [ 1] 80
col 2: *NULL*
col 3: [ 4] 4f 50 45 4e
col 4: *NULL*
col 5: [ 7] 78 73 06 01 06 0b 1a
col 6: [ 6] 53 59 53 54 45 4d
col 7: [ 4] 54 45 4d 50
col 8: [ 7] 78 6f 09 11 0a 2f 17
col 9: [ 7] 44 45 46 41 55 4c 54
col 10: [ 9] 53 59 53 5f 47 52 4f 55 50
col 11: *NULL*
col 12: [ 8] 31 30 47 20 31 31 47 20
col 13: [ 1] 4e
col 14: [ 8] 50 41 53 53 57 4f 52 44
我們可以比較一下這裡
*-----------------------------
* Rec #0x36 slt: 0x20 objn: 76757(0x00012bd5) objd: 76757 tblspc: 0(0x00000000)
* 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
包含了重要資訊Begin trans,並且RCI和RDBA均為0代表他沒有上一個UNDO REC#因為他就是開始
如此我們就形成了一個連結串列,並且知道了開始和結束的的UNDO REC#,這樣一個事物的一致性讀和
回滾也就變得理所應當了。最後給出ORACLE的一個undo chain的圖如下:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-1724306/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 回滾(ROLLBACK)和撤銷(UNDO)Oracle
- 12C關於CDB、PDB 回滾undo表空間的總結
- Oracle - 回滾表空間 Undo 的整理Oracle
- oracle回滾段 undo 表空間Oracle
- undo 事物內部結構
- 【UNDO】Oracle系統回滾段說明Oracle
- 關於Oracle的redo和undo的理解Oracle
- 由讀一致性分析undo
- Oracle基礎 03 回滾表空間 undoOracle
- 關於oracle中的undoOracle
- zt_undo 事物內部結構
- undo機制工作原理描述的:
- 關於oracle的undo_retentionOracle
- MySQL必知必會:簡介undo log、truncate、以及undo log如何幫你回滾事物MySql
- 4.3.2.4 關於CDB UNDO模式模式
- 關於Undo地實現
- 參考oracle官方文件關於髒讀、一致性讀、undo中已提交資料塊的理解Oracle
- oracle 12c 新特性 Temporary UNDO 臨時回滾段Oracle
- 閃回查詢(undo sql)SQL
- 閃回和drop原 undo tbs的一點分析
- 有關Undo表空間與回滾段的一些查詢語句記錄
- 關於前滾(roll forward)和回滾(roll back)Forward
- dump轉儲undo segment header block回滾段頭塊小方法HeaderBloC
- oracle的redo和undoOracle
- 關於依賴注入(typescript)依賴注入TypeScript
- UNDO相關查詢
- Apache Kafka內部刪除了對ZooKeeper的依賴ApacheKafka
- 關於oracle例項恢復的前滾和回滾的理解Oracle
- redo和undo的區別
- 關於undo表空間的一些常用操作
- Redo 和 Undo 概念解析
- undo log和redo log
- Innodb undo之 undo結構簡析
- Oracle的redo 和undo的區別Oracle
- MySQL undoMySql
- Innodb undo之 undo物理結構的初始化
- undo和lock視訊分享
- oracle redo和undo系列一Oracle Redo