遊戲 Lag 白皮書 › L12 資料庫
檢查點與 log flush Checkpoint / log flush stalls
原因 ID db-checkpoint · 主要負責 基礎設施團隊(DB 基礎設施)
在含圖解與實驗的完整版中開啟卡片 →
DB 定期把記憶體中的變更一次大量寫入磁碟的瞬間,查詢會變慢。
為什麼 變更累積後定期寫入磁碟 → 於是 那一刻磁碟變忙,查詢變慢 → 畫面上 存檔、載入週期性變慢
- 症狀
- 輸入延遲, 卡頓
- 因素
- 延遲
- 誰會遇到
- 整個伺服器, 只有特定功能
- 何時
- 固定週期
- 負責單位
- 主要負責 基礎設施團隊(DB 基礎設施)
- 基礎設施團隊要做的事
- 把檢查點的寫入切細、平均分散,transaction log(redo log、WAL)配置充足,使用快速的磁碟。
- 圖表上
- 固定週期飆高 · DB 查詢延遲、磁碟寫入量
- 查看位置
- PostgreSQL 看 log_checkpoints(新版本預設開啟)log 中的檢查點時間與寫入的緩衝區數、檢查點次數(17 起為 pg_stat_checkpointer 的 num_timed、num_requested,16 以下為 pg_stat_bgwriter 的 checkpoints_timed、checkpoints_req),以及 checkpoint_warning 警告。MySQL 看 SHOW ENGINE INNODB STATUS 的 LOG 區段中 Log sequence number 與 Last checkpoint at 的差距。一併疊上伺服器的磁碟寫入量與寫入延遲
- 符合的跡象
- 查詢延遲飆高的時間點與檢查點時間重疊,此時磁碟寫入量與寫入延遲往上衝。PostgreSQL 中由請求觸發的檢查點(num_requested)遠多於定時檢查點(num_timed)時,可判斷是 WAL 經常碰到 max_wal_size,使檢查點提前執行
- 不符合的跡象
- 以與檢查點時間無關的週期飆高時,是備份或批次作業(dk-backup、db-batch)
- 確認方式
- 用基礎設施工具確認(不需要遊戲程式碼)
- 深入了解
- 記錄變更的 transaction log(MySQL 的 redo log、PostgreSQL 的 WAL)設得太小時,每次 log 寫滿,DB 都得匆忙集中執行檢查點,寫入處理量會短暫大幅下降。
出處
- WAL Configuration (PostgreSQL Documentation) PostgreSQL
檢查點預設每 5 分鐘或每產生 1GB WAL(max_wal_size)執行一次,要寫出所有 dirty page,成本很高。用 checkpoint_completion_target 分散寫入,避免 I/O 暴增。檢查點間隔短於 checkpoint_warning 時,會在 log 中留下建議調高 max_wal_size 的警告 - Configuring Buffer Pool Flushing MySQL
redo log 寫滿時,緊急的(sharp)檢查點會讓處理量短暫下降;以自適應 flush(adaptive flushing)平均分散寫入 - Error Reporting and Logging (PostgreSQL Documentation) PostgreSQL
log_checkpoints:每次檢查點都在 log 中記錄寫入的緩衝區數與耗時,預設開啟 - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_checkpointer 的 num_timed(時間到而執行的檢查點)、num_requested(被請求的檢查點) - PostgreSQL 17 Release Notes PostgreSQL
新增 pg_stat_checkpointer,把檢查點相關欄位從 pg_stat_bgwriter 移過來 - The Cumulative Statistics System (PostgreSQL 16 Documentation) PostgreSQL
16 以前為 pg_stat_bgwriter 的 checkpoints_timed、checkpoints_req - InnoDB Standard Monitor and Lock Monitor Output MySQL
LOG 區段:目前的 log 序號與最後一次檢查點的位置
相關原因
同一層:L12 資料庫
同一症狀(輸入延遲)在其他層的原因
查看含圖解與實驗的完整版卡片