Checkpoint 是 InnoDB 實現崩潰恢復、緩衝池管理與 Redo Log 循環覆寫的核心機制。本文從 LSN 概念切入,系統闡述 Sharp/Fuzzy Checkpoint 四大類型觸發條件、執行流程、日誌保護水位線,並附 SHOW ENGINE INNODB STATUS 觀測指標,幫助 DBA 理解「何時刷盤、刷多少、為何阻塞」。
理想情況:Buffer Pool 裝得下所有資料、Redo Log 無限大 → 崩潰時直接 Replay 全部 Log 即可。
現實限制:
LSN (Log Sequence Number) 8 位元組遞增數字,無處不在:
觀測指令:
SHOW ENGINE INNODB STATUS\G
--- LOG ---
Log sequence number: 34778380870
Log flushed up to: 34778380870
Last checkpoint at: 34778380870
關閉資料庫時將所有髒頁刷盤。對應參數 innodb_fast_shutdown = 1(預設)。運行期不使用,否則造成長時間不可用。
僅刷新部分髒頁,四種觸發場景:
| 類型 | 觸發條件 | 髒頁來源 | 阻塞影響 | 版本演進 |
|---|---|---|---|---|
| Master Thread Checkpoint | 每秒/每 10 秒定期 | Flush List(按修改時間排序) | 異步,不阻塞 | 5.6+ 放入 Page Cleaner 線程 |
| FLUSH_LRU_LIST Checkpoint | LRU 可用頁不足(innodb_lru_scan_depth,預設 1024) | LRU List 尾部 | 5.6 前阻塞用戶線程;5.6+ Page Cleaner 異步 | 參數可調 |
| Async/Sync Flush Checkpoint | Redo Log 空間不足(水位線機制) | Flush List | 5.6 前 Async 阻塞發現線程,Sync 阻塞所有;5.6+ Page Cleaner 異步 | 核心保護機制 |
| Dirty Page Too Much Checkpoint | 髒頁比例 > innodb_max_dirty_pages_pct(預設 75%) | Flush List | 異步 | 1.0.x 前預設 90%,後 75% |
定義:
checkpoint_age = redo_lsn - checkpoint_lsn(未刷盤的 Redo 量)async_water_mark = 75% * total_redo_log_sizesync_water_mark = 90% * total_redo_log_size行為:
checkpoint_age < async_water_mark:無動作async_water_mark < checkpoint_age < sync_water_mark:Async Flush,刷足夠髒頁降至 async 線下checkpoint_age > sync_water_mark:Sync Flush,強制刷盤並阻塞(極少見,通常因 Log 檔太小或大量導入)一條 Redo Log 記錄生命週期:
Log Sequence Number (LSN1) 遞增Log Flushed Up To (LSN2)Oldest Modified Data Log (LSN3)Last Checkpoint At (LSN4)關係:LSN1 ≥ LSN2 ≥ LSN3 ≥ LSN4
除 Checkpoint 水位線,Log Buffer 亦有保護:
Buf async = 7/8 * log_buffer_size:觸發異步寫 Log FileBuf sync = 15/16 * log_buffer_size:阻塞事務強制寫 Log FileCkp async = 31/32 * total_redo_log_size:異步強制 CheckpointCkp sync = total_redo_log_size:阻塞事務強制 Checkpoint關鍵不變量:Ckp Age 永遠落後於 Buf Age,故 Buf 先觸發保護,保證 Redo Log 不會被覆寫導致資料遺失。
Log sequence number 與 Last checkpoint at 差值:過大說明刷盤跟不上,檢查 innodb_io_capacity、磁碟 IOPSinnodb_log_file_size):拉大水位線間距,減少 Sync Flush 機率innodb_io_capacity、innodb_max_dirty_pages_pct:發揮隨機 IO 優勢