指在實際數據存儲行中每一字段(entry,實際存儲不只是包括列,還有額外信息)的位置偏移量信息列表,這個位置由原點(Origin)相對位置和下一個字段計算而來。該列表保存的行中每一字段的偏移信息為倒序的,也就是說行中第一字段信息在這個列表的最後。
舉個例子:假設有三個列,第一個列的長度為1字節,第二個為2字節,第三個為4字節,這種情況下,保存三個列的偏移信息分別為[1,3(1+2),7(1+2+4)],列表倒序,轉儲的Field Start Offsets的信息應該為[07,03,01].
有兩種的特殊復雜情況:
1:偏移量數字可能為一個或兩個字節,一個字節最多允許長度為127,最高位bit用來保存是否為NULL,"Extra Bytes"部分說明了偏移量為一個字節還是兩個字節。
2:偏移量可能有一個標志信息,剩下的字節空間包含兩個段,指具體的內容。(可能這些內容並不在同一個頁中,參考後面的分析)
當偏移量為一個字節時:
1 bit = NULL
7 bit, 實際的偏移信息
當偏移量為兩個字節時:
1 bit = NULL
1 bit = 0 內容在同一個頁中,= 1 內容在不同的頁中
14 bits = 實際的偏移量,0 ~ 16383
2:EXTRA BYTES
Extra Bytes為6個字節
Name Size Description info_bits: ?? ?? () 1 bit 未使用 () 1 bit 未使用 deleted_flag 1 bit 1:刪除標志位(已刪除) min_rec_flag 1 bit 1: 預定義的最小記錄 n_owned 4 bits 擁有的記錄數量 heap_no 13 bits 堆塊中索引的數據頁序列編號 n_fields 10 bits 記錄中的字段數量 1 to 1023 1byte_offs_flag 1 bit 1:Field Start Offsets為一個字節,否則為兩個字節 next 16 bits 16 bits 下一個記錄的指針(System Column #1) TOTAL 48 bits ??
共48 bit,6個字節
如果需要通過字節讀取這存儲的記錄,最關鍵的需要讀取Extra Bytes 中的byte_offs_flag位信息,需要知道1表示偏移信息為一個字節,0表示兩個字節
如果給定了一個相對原點(Origin),InnoDB獲取記錄開始遵循如下步驟:
-- X = n_fields,這個數字等於Field Start Offsets列表中的定義的數量
-- 如果byte_offs_flag = 0,X = X * 2,每個偏移量為兩個字節表示的
-- X = X + 6,固定大小的Extra Bytes為6字節
-- 記錄的開始位置當前的位置減去X
(參照FIELD CONTENTS)
3:FIELD CONTENTS
Field Contents部分包括了記錄的所有數據,這些字段按照我們預定義的方式按順序存儲。
字段與字段沒有任何標記,記錄的結尾也沒有任何標志。
實例:
-- 創建一張表
CREATE TABLE T (FIELD1 VARCHAR(3), FIELD2 VARCHAR(3), FIELD3 VARCHAR(3)) Type=InnoDB;
需要知道的是,InnoDB下表中的每一行有6個字段,並不是3個,因為InnoDB在存儲的內容前自動補充的3個列("system columns"),這些列分別為 行ID(row ID,該表未定義主鍵),事務ID(transaction ID), 回滾指針(rollback pointer)。
-- 為該表增加三條數據
INSERT INTO T VALUES ('PP', 'PP', 'PP'); INSERT INTO T VALUES ('Q', 'Q', 'Q'); INSERT INTO T VALUES ('R', NULL, NULL);
運行工具(Borland's TDUMP)查看二進制的事務文件信息(\mysql\data\ibdata1
)
Address Values in Hexadecimal
Values in ASCII
0D4280: 00 00 2D 00 84 4F 4F 4F 4F 4F 4F 4F 4F 4F 19 17
..-..OOOOOOOOO..
0D4290: 15 13 0C 06 00 00 78 0D 02 BF 00 00 00 00 04 21
......x........!
0D42A0: 00 00 00 00 09 2A 80 00 00 00 2D 00 84 50 50 50
.....*....-..PPP
0D42B0: 50 50 50 16 15 14 13 0C 06 00 00 80 0D 02 E1 00
PPP.............
0D42C0: 00 00 00 04 22 00 00 00 00 09 2B 80 00 00 00 2D
....".....+....-
0D42D0: 00 84 51 51 51 94 94 14 13 0C 06 00 00 88 0D 00
..QQQ...........
0D42E0: 74 00 00 00 00 04 23 00 00 00 00 09 2C 80 00 00
t.....#.....,...
0D42F0: 00 2D 00 84 52 00 00 00 00 00 00 00 00 00 00 00
.-..R...........
做一下格式處理,添加標記:
19 17 15 13 0C 06 Field Start Offsets /* First Row */ 00 00 78 0D 02 BF Extra Bytes 00 00 00 00 04 21 System Column #1 00 00 00 00 09 2A System Column #2 80 00 00 00 2D 00 84 System Column #3 50 50 Field1 'PP' 50 50 Field2 'PP' 50 50 Field3 'PP' 16 15 14 13 0C 06 Field Start Offsets /* Second Row */ 00 00 80 0D 02 E1 Extra Bytes 00 00 00 00 04 22 System Column #1 00 00 00 00 09 2B System Column #2 80 00 00 00 2D 00 84 System Column #3 51 Field1 'Q' 51 Field2 'Q' 51 Field3 'Q' 94 94 14 13 0C 06 Field Start Offsets /* Third Row */ 00 00 88 0D 00 74 Extra Bytes 00 00 00 00 04 23 System Column #1 00 00 00 00 09 2C System Column #2 80 00 00 00 2D 00 84 System Column #3 52 Field1 'R'
-- "Field Start Offsets"
參照First Row,從Extra Bytes開始的7個字段,大小分別為6, 6, 7, 2, 2, 2,偏移信息指向了下一字段的開始位置,16進制表示下的數字06, 0c (6+6), 13 (6+6+7), 15 (6+6+7+2), 17 (6+6+7+2+2), 19 (6+6+7+2+2+2),倒序的Field Start Offsets值分別為:[19,17,15,13,0c,06]
-- "Extra Bytes"
參照First Row,Extra Bytes為[00 00 78 0D 02 BF],參照EXTRA BYTES讀取跳過頭21 bit讀(n_fields),取10個bit,讀取第三個字節最後三個個bit [000]和
第四個字節0D[00001101]的7個bit [0000110],得出的6即為字段的數量(除去Extra Bytes),第四個字節0D[00001101]最後bit:1表示byte_offs_flag說明偏移量為1字節,最後的第5,6字節
02 BF,指向下一行Second Row(System Column #1)的記錄(
02BF為
),下一記錄指向了System Column #1,讀取過程遵循EXTRA BYTES末的規則。0D42BF頁內地址
-- NULL列的表示
參照Third Row,FIELD2和FIELD3為NULL,因為byte_offs_flag為1,因此,在Field Start Offsets中[94 94 14 13 0C 06]每次讀取1個字節可表示字段的偏移信息,這個字節最高位為NULL標記,14 13表示1個字節[52]的FIELD1值'R',94 14表示0字節的FIELD2值NULL(94最高位為1表示NULL,其余7 bit為14),94 94表示0字節的FIELD3值NULL。