MySQL InnoDB 源碼級剖析:Page 頁結構與記錄組織機制
基於 MySQL 3.23 源碼 (fil0fil.h, page0cur.c) 深度解析 InnoDB 最小物理存儲單元 — Page (預設 16KB)。
頁類型
FIL_PAGE_INDEX:索引頁 (含 B+Tree 節點、Inode、XDES)。
FIL_PAGE_UNDO_LOG:Undo 日誌頁。
通用三層結構
+------------------+
| Page Header (38B)|
+------------------+
| Page Body (變長) |
+------------------+
| Page Trailer (8B)|
+------------------+
1. Page Header (38 字節)
| 偏移/宏 | 大小 | 含義 |
| FIL_PAGE_SPACE | 4 | 表空間 ID |
| FIL_PAGE_OFFSET | 4 | 頁號 (物理偏移) |
| FIL_PAGE_PREV | 4 | 前一頁頁號 (雙向鏈表) |
| FIL_PAGE_NEXT | 4 | 後一頁頁號 |
| FIL_PAGE_LSN | 8 | 頁最後修改對應的 Redo LSN |
| FIL_PAGE_TYPE | 2 | 頁類型 |
| FIL_PAGE_FILE_FLUSH_LSN | 8 | 表空間首頁專用:最後 flush LSN |
| FIL_PAGE_ARCH_LOG_NO | 4 | 表空間首頁專用:最後歸檔日誌序號 |
2. Page Trailer (8 字節)
- 低 4 字節:頁資料 Checksum (buf_calc_page_checksum 計算)。
- 高 4 字節:LSN 部分資訊。
- 寫入磁碟前更新、讀取時校驗,保證頁完整性。
3. Index Page Body (5 區域)
+------------------------+
| Page Header (38B) |
+------------------------+
| Body Header (56B) | <- 管理堆、目錄、方向等元數據
+------------------------+
| User Records (單向鏈表) | <- 含 Infimum/Supremum 虛擬記錄
+------------------------+
| Free Records List | <- 已刪除記錄回收鏈表
+------------------------+
| Free Heap (連續空間) | <- 新記錄優先從此分配
+------------------------+
| Page Directory (Slots) | <- 逆序存儲,每槽 2B,指向記錄鏈表
+------------------------+
| Page Trailer (8B) |
+------------------------+
Body Header 關鍵字段 (部分)
| 宏 | 偏移 | 含義 |
| PAGE_N_DIR_SLOTS | 0 | 目錄槽數量 |
| PAGE_HEAP_TOP | 2 | 堆頂空閒偏移 |
| PAGE_N_HEAP | 4 | 堆中記錄總數 |
| PAGE_FREE | 6 | 空閒記錄鏈表頭偏移 |
| PAGE_GARBAGE | 8 | 已刪除記錄總字節數 |
| PAGE_LAST_INSERT | 10 | 最後插入位置 (優化定位) |
| PAGE_DIRECTION | 12 | 插入方向 (左/右/同頁/無) |
| PAGE_N_DIRECTION | 14 | 同方向連續插入計數 |
| PAGE_N_RECS | 16 | 用戶記錄數 (不含虛擬記錄) |
| PAGE_MAX_TRX_ID | 18 | 修改頁最大事務 ID |
| PAGE_LEVEL | 28 | B+Tree 層級 (0=葉節點) |
| PAGE_BTR_SEG_LEAF | 36 | 葉節點段頭 |
| PAGE_BTR_SEG_TOP | 36+FSEG_HEADER_SIZE | 非葉節點段頭 |
記錄組織:單向鏈表 + 目錄槽 (Page Directory)
- Infimum (最小) 與 Supremum (最大) 虛擬記錄固定在 Body Header 後,所有用戶記錄夾在中間。
- 目錄槽逆序存儲 (最後 2 字節屬 Infimum),每槽管理 4~8 條記錄 (n_owned),槽指向該組最後一條記錄。
- 查找:目錄槽二分查找 → 組內記錄二分查找 (利用 n_owned)。
- 分裂/合併:槽超限分裂、低於閾值合併,平衡空間與查找效率。
頁操作 (page0cur.c)
- 游標
page_cur_t 指向當前操作記錄 (僅內存有效)。
- 搜尋:
page_cur_search_with_match 支援 GT/GE/LT/LE 四種模式。
- 插入:定位前驅 → 修改鏈表指針 → 更新槽 n_owned → 必要時分裂槽 → 記錄 MTR Redo Log。
- 刪除:修改鏈表 → 記錄 MTR Log → 加入 Free List → 更新 PAGE_GARBAGE → 必要時合併槽。
批量操作
提供 page_copy_rec_list、page_delete_rec_list 等批量拷貝/刪除介面,建立在單記錄操作之上。
理解 Page 結構是掌握 InnoDB 存儲引擎、索引組織、鎖機制、崩潰恢復的基石。
- 上一篇文章: Windows 安裝 MySQL 社區版 (ZIP 免安裝包) 完整步驟:解壓、環境變數、註冊服務、啟動
- 下一篇文章: MySQL 批量刪除表:利用 information_schema 動態生成 DROP 語句
Copyright ©
程式碼之家 All Rights Reserved