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

InnoDB 源碼深度分析:事務日誌結構與 Redo Log Block 解析(二)

     編輯:MySQL 綜合教學

InnoDB 源碼深度分析:事務日誌結構與 Redo Log Block 解析(二)

接續前文基本概念,本文深入源碼層面剖析 Redo Log Block 結構、頭尾部元數據、跨 Block 日誌寫入機制,為理解 WAL、檢查點、崩潰恢復奠定基礎。

Redo Log Block 物理結構

InnoDB 以 512 位元組為單位管理 Redo Log(OS_FILE_LOG_BLOCK_SIZE),每個 Block 包含:

+------------------+------------------+------------------+------------------+
| Header (12 bytes) |    Log Data (496 bytes)    | Trailer (4 bytes) |
+------------------+------------------+------------------+------------------+

Header 結構(log/sys/pars0pars.h)


#define LOG_BLOCK_HDR_NO            0   // Block 序號(4 bytes),最高位=1 表示 flush 寫入段首塊
#define LOG_BLOCK_HDR_DATA_LEN      4   // 本 Block 實際日誌資料長度(2 bytes)
#define LOG_BLOCK_FIRST_REC_GROUP   6   // 本 Block 內第一個 MTR 日誌組起始偏移(2 bytes),0=無
#define LOG_BLOCK_CHECKPOINT_NO     8   // 寫入時最新 checkpoint_no 低 4 位元組(4 bytes)
#define LOG_BLOCK_HDR_SIZE         12   // Header 總長

Trailer 結構


#define LOG_BLOCK_CHECKSUM  4   // CRC32 校驗和(4 bytes),從 Block 尾部向前
#define LOG_BLOCK_TRL_SIZE  4   // Trailer 總長

關鍵機制:LOG_BLOCK_FIRST_REC_GROUP

MTR (Mini-Transaction) 日誌可能跨 Block。當一個 MTR 日誌 > 496 bytes 時:

Block N: [Header] [Log Data: 前 496 bytes] [Trailer]
Block N+1: [Header] [剩餘 4 bytes] [新 MTR 從 offset 16 開始] [Trailer]
         ↑ LOG_BLOCK_FIRST_REC_GROUP = 16

作用:崩潰恢復時,從該偏移開始解析完整 MTR,避免從截斷處誤解析。

原始碼驗證(log/log0log.h)


// 寫入時更新 FIRST_REC_GROUP
if (len == 0) {
    // 本 Block 尚無完整 MTR,記錄潛在起始位置
    mach_write_to_2(block + LOG_BLOCK_FIRST_REC_GROUP, LOG_BLOCK_HDR_DATA_LEN);
} else {
    // 有完整 MTR 起始於此
    mach_write_to_2(block + LOG_BLOCK_FIRST_REC_GROUP, len);
}

Checkpoint 與 Block 關係

LOG_BLOCK_CHECKPOINT_NO 記錄寫入該 Block 時的最新 checkpoint 序號(低 32 位)。用於:

  • 恢復時確定哪些 Block 已持久化至檢查點
  • 避免重複應用已檢查點的日誌

實際可用資料空間計算


512 (Block) - 12 (Header) - 4 (Trailer) = 496 bytes Log Data

這也是為什麼大 MTR 必須跨 Block 寫入的原因。

圖解:跨 Block MTR 寫入

MTR 1 (500 bytes) 寫入流程:
1. Block 100: Header + 496 bytes (MTR 1 前段) + Trailer
   FIRST_REC_GROUP = 0 (Block 100 內無新 MTR 起始)

2. Block 101: Header + 4 bytes (MTR 1 尾段) + 100 bytes (MTR 2 完整) + Trailer
   FIRST_REC_GROUP = 16 (MTR 2 起始於 offset 16,即 Header 12 + MTR 1 尾段 4)

源碼學習路徑建議

  1. log/log0log.h - 核心常數、結構定義
  2. log/log0log.cc - 日誌寫入、flush、檢查點主流程
  3. log/log0recv.cc - 崩潰恢復解析邏輯
  4. mtr/mtr0mtr.cc - MTR 生成與提交
  5. log/log0chkp.cc - 檢查點協調

下一步預告

下文將分析:

  • Log Buffer 管理與 flush 觸發條件
  • innodb_flush_log_at_trx_commit 三種模式源碼實現
  • Group Commit 實現機制
  • 檢查點推進與 LSN 協調

理解 Redo Log Block 結構,是掌握 InnoDB 事務持久化、崩潰恢復、複制同步核心機制的鑰匙。

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