Oracle RedoLog-二進制格式分析,文件頭,DML,DDL

上篇文章,簡單介紹了 RedoLog 是什麼,以及怎麼從 Oracle Dump 二進制日誌。接下來,分析下 Redo Log 二進制文件的格式,主要包括:文件頭重做日誌頭DML-INSERT 操作DDL-CREATE 操作

Redo Log 二進制文件中,採用的是小端序字節序。

原文鏈接:https://www.chuonye.com/archives/oracle-redolog-format.html

1. File Header

文件頭,佔用第一個塊。Oracle 中許多二進制的數據和日誌文件都有相似的格式,在線日誌 Redo Log 文件也是如此。下圖是 RedoLog 文件開始的前 80 字節。

file-header

File Type

2字節 表示文件類型,區分不同的 Oracle 文件,比如,在 10g 版本中:

  • 0xA2 表示數據文件,Data File
  • 0xC2 表示控制文件,Control File
  • 0x22 表示重做日誌文件,Redo Log File

Oracle 數據庫其實就是由一堆文件組成的。

Block Size

偏移量 20,長度 2字節,存儲的是塊大小,它的值是固定的,只會因操作系統而不同。在 Windows, Linux 和 Solaris 上,塊大小爲 512字節–0x0200,而 HP-UX 的塊大小爲 1024。

另外,每個塊都有一個 16字節 的塊頭,稍後會介紹它。

Number of Blocks

偏移量 24,長度 4字節,存儲的是文件中的塊數,不包括文件頭本身使用的塊,可以這樣計算出整個文件的大小:

(0x00019000 + 1) * 512 = 52429312 (50MB)

Magic

魔數只是文件標識,用來檢查是否是 Oracle 文件。

Block Header

每個塊都有一個 16字節 的頭部,即使一個 Redo Record 橫跨多個塊,解析時這一點尤爲重要。

block-header

上圖黃色指示的是一個頭部示例,每個塊頭都是以簽名 0x0122 開頭,其中:

  • 偏移量 4,長度 4字節,存儲的是塊在文件中的編號
  • 偏移量 8,長度 4字節,存儲的是日誌序號
  • 偏移量 12,長度 1字節,存儲的是 Record 在該塊內的字節偏移量

這三個值正好是 Record 的 RBA 內容。

最後偏移量 14,長度 2字節,存儲的是校驗和,用於驗證數據是否完整,驗證的邏輯這裏就不記錄了,感興趣的可以在上篇描述的 PDF 文件內找到。

2. Redo Log Header

重做日誌頭,佔用第二個塊。這裏包含的信息就多了,如數據庫SID,數據庫版本和開始記錄的時間等。

redolog-header

3. Redo Record

Redo Record 包含一個 SCN 中的所有操作,由一個頭和一個或多個 change vector 組成。比如往一個有索引的表中插入一條數據,會創建以下內容:

  • 爲 INSERT 操作,分別創建 redo changeundo change
  • 爲索引改動,分別創建 redo changeundo change
  • 一個事務開始 change,一個事務提交 change

其中的每個 Change 都有一個操作碼,用於區分,常見的操作碼:

  • 5.1:撤銷修改 - Undo Record
  • 5.2:事務開始
  • 5.4:事務提交 - Commit
  • 11.2:插入一行數據
  • 11.3:刪除一行數據
  • 11.11:插入多行數據
  • 11.19:更新多行數據
  • 10.2:插入一個索引 - INSERT LEAF ROW
  • 10.4:刪除一個索引 - DELETE LEAF ROW
  • 13.1:申請空間 - CREATE TABLE 後
  • 24.1:DDL 操作

4. DML-INSERT

增刪改是數據庫基本操作,下圖顯示的是一個插入操作 Record 轉成十六進制的信息。

redolog-header

Block 頭的第 12 個字節 0x10,表示 Record 開始字節在偏移量 16字節 處;

Record 開始的前 2字節 表示長度,最大爲 65536字節,因此它可能需要多個 block 存儲。這裏長度是 0x01A8=424 一個 block 足以存儲。之後的第4個字節是 Record 頭長度標識 VLD,具體數值取決於 Record 類型,這裏的 0x0D 表示頭長度爲 0x44=68

跳過 0x44字節 就能找到第一個 Change Vector,操作碼是 0x0B02 - 11.2,即 INSERT 操作。在操作碼後的第22字節,可以找到插入對象的ID,這裏是 0x0057 - 87,在字典表 dba_objects 查詢 data_object_id=87 的記錄可知插入的表爲 SYS.SYSAUTH$

跳過 0x44+0x18字節,開始的2字節 0x000C=12 表示第一個 Change 的元素長度列表的長度,元素長度佔用 2字節,12字節表示除頭2字節外,總共有 (12-2)/2=5 個 長度元素,這意味着插入了 3個 字段內容。

  • 0x00140x0031:這兩個值是半固定的,表示 KTBKDO 的長度
  • 0x0002:表示插入第一列的數據字節數爲 2字節
  • 0x0002:表示插入第二列的數據字節數也爲 2字節
  • 0x0003:表示插入第三列的數據字節數爲 3字節

上面的長度計算的是實際長度,但在計算偏移量是都需要 4字節對齊。跳過指定的字節後,可以得到三個字段的值爲:

  • 0xC102:表示的內容爲 數字 1
  • 0xC105:表示的內容爲 數字 4
  • 0xC20931:表示的內容爲 數字 848

結合 SYSAUTH$ 的字段就能還原 SQL:

SQL> INSERT INTO SYS.SYSAUTH$ (GRANTEE#,PRIVILEGE#, SEQUENCE#) VALUES (1,4,848); 

再往後有兩個 Change,0x05020x05010x0502 可以解析出此次事務的 XID0x0501 是撤銷操作,INSERT 對應的就是 DELETE。

5. DDL-CREATE

雖然 DDL 語句已寫入 Redo Log 文件中,但是在使用 ALTER SYSTEM DUMP LOGFILE 命令後,結果中沒有語句,內容如下:

REDO RECORD - Thread:1 RBA: 0x000082.0000febf.002c LEN: 0x00f4 VLD: 0x01 
SCN: 0x0000.003a061f SUBSCN:  1 03/13/2007 13:55:41 
CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ:  0 OP:24.1 

操作碼 24.1 表明是 DDL 操作。從 RBA 中,可以看到塊編號爲 0x0000febf (65215),塊大小爲 512,所以該操作在二進制文件的偏移量爲 512*65215=33390080 ,十六進制爲 0x01FD7E00

ddl-location

可以清楚的看到 DDL 語句:

create user wiggywiggywiggy identified by VALUES '2FA1749D698AD874'

對應二進制格式映射信息是:

ddl-format

6. 總結

本文簡單描述了二進制格式具體是什麼,實際分析的時候也是這樣,把二進制文件打開轉成 16進制顯示,一個字節一個字節的分析。如果做過網絡編程,特別是 TCP 私有協議設計和解析,應該很容易理解。

下一篇會介紹解析的一些問題,比如 Record 頭長度怎麼計算,Rowid 怎麼計算等等。

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