Oracle RedoLog-二進制格式分析,文件頭,DML,DDL
- 2021 年 1 月 8 日
- 筆記
- oracle redolog
上篇文章,簡單介紹了 RedoLog 是什麼,以及怎麼從 Oracle Dump 二進制日誌。接下來,分析下 Redo Log 二進制文件的格式,主要包括:文件頭,重做日誌頭,DML-INSERT 操作,DDL-CREATE 操作。
Redo Log 二進制文件中,採用的是小端序位元組序。
原文鏈接://www.chuonye.com/archives/oracle-redolog-format.html
1. File Header
文件頭,佔用第一個塊。Oracle 中許多二進制的數據和日誌文件都有相似的格式,在線日誌 Redo Log 文件也是如此。下圖是 RedoLog 文件開始的前 80 位元組。
File Type
前 2位元組
表示文件類型,區分不同的 Oracle 文件,比如,在 10g 版本中:
0xA2
表示數據文件,Data File0xC2
表示控制文件,Control File0x22
表示重做日誌文件,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 橫跨多個塊,解析時這一點尤為重要。
上圖黃色指示的是一個頭部示例,每個塊頭都是以簽名 0x0122
開頭,其中:
- 偏移量
4
,長度4位元組
,存儲的是塊在文件中的編號 - 偏移量
8
,長度4位元組
,存儲的是日誌序號 - 偏移量
12
,長度1位元組
,存儲的是 Record 在該塊內的位元組偏移量
這三個值正好是 Record 的 RBA 內容。
最後偏移量 14
,長度 2位元組
,存儲的是校驗和,用於驗證數據是否完整,驗證的邏輯這裡就不記錄了,感興趣的可以在上篇描述的 PDF 文件內找到。
2. Redo Log Header
重做日誌頭,佔用第二個塊。這裡包含的信息就多了,如數據庫SID,數據庫版本和開始記錄的時間等。
3. Redo Record
Redo Record 包含一個 SCN 中的所有操作,由一個頭和一個或多個 change vector
組成。比如往一個有索引的表中插入一條數據,會創建以下內容:
- 為 INSERT 操作,分別創建
redo change
和undo change
- 為索引改動,分別創建
redo change
和undo 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 轉成十六進制的信息。
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個
字段內容。
0x0014
和0x0031
:這兩個值是半固定的,表示 KTB 和 KDO 的長度0x0002
:表示插入第一列的數據位元組數為2位元組
0x0002
:表示插入第二列的數據位元組數也為2位元組
0x0003
:表示插入第三列的數據位元組數為3位元組
上面的長度計算的是實際長度,但在計算偏移量是都需要 4位元組對齊。跳過指定的位元組後,可以得到三個字段的值為:
0xC102
:表示的內容為 數字 10xC105
:表示的內容為 數字 40xC20931
:表示的內容為 數字 848
結合 SYSAUTH$ 的字段就能還原 SQL:
SQL> INSERT INTO SYS.SYSAUTH$ (GRANTEE#,PRIVILEGE#, SEQUENCE#) VALUES (1,4,848);
再往後有兩個 Change,0x0502
和 0x0501
。0x0502
可以解析出此次事務的 XID;0x0501
是撤銷操作,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 語句:
create user wiggywiggywiggy identified by VALUES '2FA1749D698AD874'
對應二進制格式映射信息是:
6. 總結
本文簡單描述了二進制格式具體是什麼,實際分析的時候也是這樣,把二進制文件打開轉成 16進制顯示,一個位元組一個位元組的分析。如果做過網絡編程,特別是 TCP 私有協議設計和解析,應該很容易理解。
下一篇會介紹解析的一些問題,比如 Record 頭長度怎麼計算,Rowid 怎麼計算等等。