首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL InnoDB 行存儲底層結構深度解析:Field Start Offsets、Extra Bytes、Field Contents 三大組成

     編輯:MySQL 綜合教學

MySQL InnoDB 行存儲底層結構深度解析:Field Start Offsets、Extra Bytes、Field Contents 三大組成

InnoDB 頁面中的行記錄並非簡單的列值拼接,而是由 Field Start Offsets(偏移量數組)、Extra Bytes(額外元數據)、Field Contents(實際數據) 三部分組成的緊湊結構。理解其佈局,是讀懂頁面十六進制轉儲、分析記錄遷移、實現工具級解析的基石。

行記錄整體佈局(自低地址向高地址)

+------------------------+  ← Origin (記錄起始地址)
| Field Contents         |  實際列數據(含系統列),按定義順序緊湊存儲
|   (系統列: row_id, trx_id, roll_ptr) |
|   (用戶列: col1, col2, ...)          |
+------------------------+
| Extra Bytes (6 bytes)  |  固定 6 字節元數據區
+------------------------+
| Field Start Offsets    |  變長偏移量數組(倒序),每項 1 或 2 字節
|   (倒序: 最後一列偏移在最前)          |
+------------------------+  ← 頁面高地址方向

1. Field Start Offsets(偏移量數組)

  • 作用:記錄每個字段(含系統列)相對 Origin 的偏移量,倒序存儲,便于從 Extra Bytes 向前定位各字段。
  • 編碼規則:
    • 每項 1 字節(1 byte_offs_flag=1):高位 bit 為 NULL 標記(1=NULL),低 7 位存偏移值(0-127)。
    • 每項 2 字節(1 byte_offs_flag=0):高位 bit1=NULL,bit2=外部存儲標記(1=溢出頁),低 14 位存偏移值(0-16383)。
  • 示例:三用戶列,長度 1,2,4 字節。偏移值依次為 1, 3(1+2), 7(1+2+4)。倒序數組:[07, 03, 01]。

2. Extra Bytes(6 字節固定元數據)

位範圍名稱含義
bit 0-1reserved保留未用
bit 2deleted_flag1=記錄已刪除(標記刪除,未立即物理移除)
bit 3min_rec_flag1=頁目錄中的最小記錄(Infimum)
bit 4-7n_owned頁目錄槽擁有的記錄數(0-15)
bit 8-20heap_no堆中記錄序號(從 0 開始,Infimum=0, Supremum=1)
bit 21-30n_fields記錄字段數(1-1023,含系統列)
bit 311byte_offs_flag1=偏移量 1 字節;0=2 字節
bit 32-47next_record下一條記錄相對頁起始的偏移(16 位),構成單向鏈表

共 48 bits = 6 bytes。解析時必須先讀取 1byte_offs_flag 確定偏移量編碼長度。

3. Field Contents(實際數據區)

  • 按表定義順序存儲:先 3 個系統列(row_id 6B、trx_id 6B、roll_ptr 7B),再用戶列。
  • 無分隔符、無結束標記,完全依賴偏移量數組定位。
  • NULL 列不占用數據區空間,僅在偏移量高位標記 NULL。
  • 變長列(VARCHAR/VARBINARY/TEXT/BLOB)長度前綴:1 字節(長度<255)或 2 字節(長度≥255)。

實戰:十六進制轉儲解析演示

建表 CREATE TABLE t(f1 VARCHAR(3), f2 VARCHAR(3), f3 VARCHAR(3)) ENGINE=InnoDB;
插入三行:('PP','PP','PP')、('Q','Q','Q')、('R',NULL,NULL)。
工具 tdump 讀取 ibdata1 相關頁面片段:

Row 1 (Origin 假設 0x0D42A0):
Extra Bytes: 00 00 78 0D 02 BF
  → n_fields=6 (3系統+3用戶), 1byte_offs_flag=1, next=0x02BF
Offsets (倒序): 19 17 15 13 0C 06
  → 對應偏移 6,12,19,21,23,25 (十進制)
Contents: [系統列 6+6+7=19B] + 'PP'(2) + 'PP'(2) + 'PP'(2) = 25B 吻合

Row 3 (含 NULL):
Offsets: 94 94 14 13 0C 06
  → 0x94=10010100b, 高位1=NULL, 低7位=0x14=20 → 偏移20, 長度0
  → 兩個 0x94 連續表示 f2、f3 均為 NULL

從 Origin 定位記錄起始的算法

給定 Origin 指針(指向 Extra Bytes 末尾下一字節):
X = n_fields
IF 1byte_offs_flag == 0: X = X * 2
X = X + 6  -- Extra Bytes 固定 6 字節
Record_Start = Origin - X

系統列詳解

系統列大小含義
row_id (DB_ROW_ID)6 bytes無顯式主鍵時的隱藏單調遞增 ID
trx_id (DB_TRX_ID)6 bytes最後修改該記錄的事務 ID,支撐 MVCC
roll_ptr (DB_ROLL_PTR)7 bytes指向 Undo Log 版本鏈的指針

總結

InnoDB 行格式是緊湊、自描述、支持變長與 NULL的精妙設計。掌握「偏移量倒序 + Extra Bytes 元數據 + 內容區」三位一體結構,可實現:

  • 頁面級數據恢復工具開發
  • 非標準工具解析 Binlog/Redo Log
  • 深度理解 ROW_FORMAT=COMPACT/REDUNDANT/DYNAMIC/COMPRESSED 差異

建議配合 innodb_ruby、page_parser 等開源工具實戰演練。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved