InnoDB 透過 Redo Log (重做日誌) 實現交易持久性與崩潰恢復。本文深入剖析 Log Buffer、Data Buffer 交互、三種觸發寫盤機制、Fuzzy Checkpoint 與恢復流程。
核心組件
- Log Buffer:記憶體中循環緩衝區,儲存 Redo Log Records (預設 16MB 起)
- Data Buffer (Buffer Pool):快取資料頁,修改後標記為 dirty page
- LSN (Log Sequence Number):日誌記錄在檔案中的位移,也是版本號,關鍵同步點
更新流程示例:INSERT
- Log Buffer 追加
Log Record #5 (含 rowid 與新記錄內容) → Redo 記錄
- Data Buffer 對應頁面新增行,頁頭標記
LSN = #5
- 此時 Log Buffer LSN ≥ Data Page LSN,滿足 WAL (Write-Ahead Logging) 原則
三種觸發寫盤機制
1. Log Buffer 滿**
- 循環覆寫:新記錄覆蓋最舊記錄
- 極少發生,InnoDB 會主動預寫防止
2. Data Buffer 滿 (Dirty Page 刷盤)**
- 選擇 LRU 尾部 dirty page 刷盤
- 關鍵檢查:Data Page 頁頭 LSN ≤ 當前 Log File 最新 LSN
- 若不滿足 → 強制先刷 Redo Log 至該 LSN (WAL 強制)
3. Checkpoint (模糊檢查點)**
- 專用背景執行緒定期喚醒
- 目標:(a) 限制 Log/Data Buffer 佔用 (b) 確保 Log 先於 Data 寫盤 (c) 無 Data Page LSN 落於已被覆蓋的 Log 區間
- 非 Sharp Checkpoint (全量刷盤),而是增量、分批推進 → Fuzzy Checkpoint
Commit 時的行為
- 僅確保 Redo Log 刷盤 (由
innodb_flush_log_at_trx_commit 控制)
- Dirty Page 不在 Commit 時刷盤,僅在 Checkpoint 或 Buffer 滿時刷盤
- 因 Dirty Page 內容可由 Redo Log 重做,屬多餘資料
崩潰恢復流程
- 讀取最新 Checkpoint LSN
- 掃描 Checkpoint 之後的 Redo Log
- 對每個受影響頁面:
若頁面 LSN < Log Record LSN → Redo 重做 (Rolling Forward)
若頁面 LSN ≥ Log Record LSN → 已刷盤,跳過
- 完成後資料庫達到一致狀態
關鍵配置參數
| 參數 | 建議/說明 |
innodb_log_file_size | 單個日誌檔大小,總量 = size × group。大檔減少 Checkpoint 壓力,但恢復時間變長 |
innodb_log_files_in_group | 日誌檔組數 (通常 2) |
innodb_log_buffer_size | Log Buffer 大小 (16-64MB),大交易需調大 |
innodb_flush_log_at_trx_commit | 1=最安全 (每提交 fsync)、2=每秒 fsync、0=僅寫 OS 快取 |
innodb_fast_shutdown | 1=快速關機 (跳過刷盤)、0=完整刷盤、2=冷備份模式 |
理解 Redo Log 機制,能指導生產環境參數調優、故障恢復預案制定、以及備份工具 (如 Percona XtraBackup) 原理掌握。