游戏卡顿白皮书 › L12 数据库
检查点/日志刷盘 Checkpoint / log flush stalls
原因 ID db-checkpoint · 主责 运维团队·数据库运维
在含图示和实验的完整版中打开此卡片 →
DB 定期把内存中的变更集中写入磁盘,那一刻查询会变慢。
起因 变更累积后定期写入磁盘 → 结果 那一刻磁盘变忙,查询变慢 → 画面表现 存盘、加载周期性变慢
- 症状
- 操作延迟, 一卡一卡
- 因素
- 延迟
- 谁会遇到
- 全服, 仅特定功能
- 何时出现
- 固定周期
- 负责方
- 主责 运维团队·数据库运维
- 运维团队要做的事
- 把检查点拆细、均匀摊开,事务日志(redo log、WAL)留足容量,使用更快的磁盘。
- 监控图上
- 周期性尖峰 · DB 查询延迟、磁盘写入量
- 查看位置
- PostgreSQL 看 log_checkpoints(较新版本默认开启)日志中的检查点时间和写出的缓冲区数,检查点次数(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)
- 确认手段
- 运维工具即可确认(无需游戏代码)
- 深入了解
- 记录变更的事务日志(MySQL 的 redo log、PostgreSQL 的 WAL)设得太小,每次日志写满,DB 都要仓促地集中做检查点,写入吞吐量会一阵一阵地大幅下降。
出处
- WAL Configuration (PostgreSQL Documentation) PostgreSQL
检查点默认每 5 分钟或每 1 GB WAL(max_wal_size)执行一次,要写出所有脏页,开销大。用 checkpoint_completion_target 把写入摊开,避免 I/O 激增。检查点间隔短于 checkpoint_warning 时,日志里会记录建议调大 max_wal_size 的警告 - Configuring Buffer Pool Flushing MySQL
redo log 写满时会触发急促的(sharp)检查点,吞吐量短暂下降;自适应刷新(adaptive flushing)把写入均匀摊开 - Error Reporting and Logging (PostgreSQL Documentation) PostgreSQL
log_checkpoints:每次检查点把写出的缓冲区数和耗时记入日志,默认开启 - 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 部分:当前日志序列号和最后一个检查点的位置
相关原因
同一层:L12 数据库
其他层中同样导致“操作延迟”的原因
查看含图示和实验的原卡片