從ITL到Undo前映象提取實驗
“多版本一致讀”是Oracle資料庫的一個重要特性。Oracle中,一個資料行,如果正在進行資料塊修改操作,而且尚未提交。其他會話的使用者select的資料是該事務修改之前的資料行資料,也就是其“前映象”。這樣,Oracle中的Select操作是不會被DML事務所阻塞。
讀取資料塊的前映象,是基於Oracle Undo機制完成的。當一個資料塊要發生事務修改時,會將當前的資料資訊複製到Undo Segment的相應位置中。並且作為發生的事務transaction,也會關聯上對應Undo Segment中特定的位置資訊。
上面的過程有一個重要細節:Undo Segment的前映象寫入操作,同樣是有Redo Log Entry生成,記錄入Redo Log的。只有這樣,才能保證在進行Instance Recovery的過程中,Oracle進行事務前滾、後滾操作時,可以完全Replay Transaction。
當Select操作要檢索一個正在進行事務的資料行時,Oracle會根據該行上對應的事務對應的Undo Block Address(UBA)定位到該資料行的前映象資訊。再到Undo Tablespace中找前映象資料。
本文計劃從資料塊ITL(Interest Transaction List)事務槽入手,層層定位,演示找到事務資料行對應前映象的過程。
1、環境準備
我們選擇10gR2資料庫,使用的環境和資料表同筆者上文《從Dump資料塊看ITL》(http://space.itpub.net/17203031/viewspace-716353)。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
此時實驗資料和Trace跟蹤檔案位置如下:
SQL> select * from t;
ID VNAME
---------- ----------
1 id
2 iddf
SQL> select id, dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, dbms_rowid.rowid_row_number(rowid) rowno from t;
ID FNO BNO ROWNO
---------- ---------- ---------- ----------
1 1 65266 0
2 1 65266 1
SQL> select f_get_trace_name from dual;
F_GET_TRACE_NAME
--------------------------------------------------------------------------------
C:\TOOL\ORACLE\ORACLE\PRODUCT\10.2.0\ADMIN\OTS\UDUMP\ots_ora_4524.trc
我們Dump出初始的事務ITL列表,如下:
--此時ITL情況
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0007.02a.000085d4 0x00800ca8.35fc.09 C--- 0 scn 0x078c.7f2ddad3
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
注意:預設情況下,Oracle資料塊的ITL事務槽初始數目是2。但是在上篇的實驗中,我們實驗過三個會話事務,用於測試ITL自動延展。現在發現,擴充的ITL列表物件並沒有收縮。這說明:ITL一旦擴充,是不會回收縮減的。
2、事務資訊定位解析
首先,我們開啟一個會話進行實驗。
SQL> update t set vname='d' where id=1;
1 row updated
SQL> select addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, xid from v$transaction;
ADDR XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC XID
-------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------------
27F8EDCC 6 9 34214 2 1762 13420 40 06000900A6850000
注意,在v$transcation中,我們是可以方便的定位到事務標記資訊和對應的Undo Segment Block資訊的。一個Oracle事務,在定位上是透過usn, slot和sqn唯一確定事務。注意上面程式碼中的三個標記,我們可以從Dump出的ITL中定位到這些資訊。
使用dump命令將對應資料塊的資訊dump出。
--將資料塊DUMP出
SQL> alter system dump datafile 1 block 65266;
System altered
--ITL片段
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0007.02a.000085d4 0x00800ca8.35fc.09 C--- 0 scn 0x078c.7f2ddad3
0x02 0x0006.009.000085a6 0x008006e2.346c.28 ---- 1 fsc 0x0000.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
注意ITL02的槽位,從LCK資訊上看,正在進行一個事務。對應的xid為“0x0006.009.000085a6”。這三個十六進位制組成的程式碼,正好標註出事務的ID編號。
我們可以使用to_number函式將三個片段資料進行十六進位制解析。
SQL> select to_number('0006','xxxxx') from dual;
TO_NUMBER('0006','XXXXX')
-------------------------
6 -–與v$transaction中的xidusn對應
SQL> select to_number('009','xxxxx') from dual;
TO_NUMBER('009','XXXXX')
------------------------
9 -–與v$transaction中的xidslot對應
SQL> select to_number('85a6','xxxxx') from dual;
TO_NUMBER('85A6','XXXXX')
-------------------------
34214 -–與v$transaction中的xidsqn對應
說明ITL02的確是對應我們會話事務。
從事務槽中,我們看到了UBA(Undo Block Address)資訊,為“0x008006e2.346c.28”。UBA的格式解析為:dba+seq#+rec#。其中的dba為對應的資料檔案和資料塊的地址。
下面我們需要做的,就是定位到Undo片段的位置。
3、Undo位置確定和前映象匯出
我們需要從UBA地址找到前映象儲存的物理位置,也就是Undo塊上的特定片段。首先從DBA中分析出地址。
--將16進位制DBA翻譯為十進位制格式;
SQL> select to_number('8006e2','xxxxxxxx') from dual;
TO_NUMBER('8006E2','XXXXXXXX')
------------------------------
8390370
--使用dbms_utility方法實現轉換;
SQL> select dbms_utility.data_block_address_file(8390370) file_no, dbms_utility.data_block_address_block(8390370) block_no from dual;
FILE_NO BLOCK_NO
---------- ----------
2 1762
定位到Undo Block的編號是在fno=2,blockno=1762的位置上。下面需要將其dump出。
SQL> alter system dump datafile 2 block 1762;
System altered
匯出的Undo Block格式和一般資料塊的Dump結果格式完全不相同。需要說明,一個Undo Block內部的內容可能很多,但是針對需要的前映象資訊,需要透過UBA中的seq#和rec#來確定。
我們首先可以從dump檔案中,根據xid編號,找到事務片段。
**************************************************************
UNDO BLK:
xid: 0x0006.009.000085a6 seq: 0x346c cnt: 0x28 irb: 0x28 icl: 0x0 flg: 0x0000
cnt對應的就是UBA中的rec#,而seq對應UBA中的Seq。找到片段如下:
*-----------------------------
* Rec #0x28 slt: 0x09 objn: 112888(0x0001b8f8) objd: 112888 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: 0x00000000
*-----------------------------
uba: 0x008006e2.346c.27 ctl max scn: 0x078c.7f2eae5b prv tx scn: 0x078c.7f2eae65
txn start scn: scn: 0x078c.7f2eb238 logon user: 0
prev brb: 8390369 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x0040fef2 hdba: 0x0040fef1
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 10
ncol: 2 nnew: 1 size: 1
col 1: [ 2] 69 64
對應的col,就是前映象資料的體現。我們的update語句修改的是vname列,與col 1相對應。
我們可以將”69 64”翻譯為可讀格式,判斷我們的想法。
set serveroutput on;
declare
n varchar2(10);
begin
dbms_stats.convert_raw_value('6964',n);
dbms_output.put_line(n);
end;
/
SQL>
id
PL/SQL procedure successfully completed
前映象取值為id,與預想相同。
4、結論
本文簡單介紹瞭如何從一個事務入手,找到前映象資料的基本方法。我們文中是從itl入手進行研究的,還有可以從v$transaction檢視中進行查詢UNDO地址資訊,效果相同。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-716623/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle實驗記錄 (dump undo)Oracle
- Docker映象中提取DockerfileDocker
- oracle實驗記錄 (dump undo4)Oracle
- oracle實驗記錄 (dump undo3)Oracle
- oracle實驗記錄 (dump undo2)Oracle
- 從 ISO 映象中提取和複製檔案的絕招(Linux)Linux
- 關於ITL以及UNDO SEGMENT HEADER 事物表(tx table)闡述Header
- 從Dump資料塊看ITL
- 從MVC到前後端分離MVC後端
- SQL SERVER 2005映象實驗SQLServer
- 從10.2.0.1升級到10.2.0.5操作實驗(下)
- 從10.2.0.1升級到10.2.0.5操作實驗(上)
- Python程式設計從0到1(實戰篇:提取Word表格儲存到Excel)Python程式設計Excel
- 查詢時間從前7天到當前時間
- ITL中xid 和 uba的驗證!
- 從思路到工具 - 增長實驗資料歸因分析
- 初體驗Sonar10.6 之 從部署到實戰
- 從前後端分離到GraphQL,攜程如何用Node實現?\n後端
- ITL
- 一步步從後端渲染到前後端分離經驗分享(1)後端
- oracle實驗記錄 (oracle 10G 詳細分析undo)Oracle
- Jib構建映象問題從定位到深入分析
- 字串擷取從前幾位到後幾位字串
- 2024從國慶到CSP前總結
- 那些年的QQ空間-從前到後實現圖片上傳(1)
- 爬蟲工作原理詳解:從網頁請求到資料提取爬蟲網頁
- Jenkins流水線(pipeline)實戰之:從部署到體驗Jenkins
- Mac下vagrant從安裝到體驗Mac
- 從字串中提取數字字串
- react技術棧實踐(從前到後擼一個電影蒐集應用)React
- 關於意義:從現實到遊戲,從自我到自由遊戲
- 提取檔名字到excel表中Excel
- Flink1.7從安裝到體驗
- 從入門到菜鳥的經驗分享
- 體驗 Java 9(1):從 Hello World 到 LombokJavaLombok
- java從字串中提取數字Java字串
- 從配置檔案中提取IP
- 4.0體驗站|OceanBase 4.0,從分散式到單機,從單機到分散式分散式