checkpoint_completion_target建议设为0.9,oltp场景下只要磁盘吞吐≥200mb/s即可;若checkpoint_write_time占比超30%,可降至0.7并调大max_wal_size;严禁设为1.0。

checkpoint_completion_target 设置多少才不拖慢写入
这个参数决定 PostgreSQL 在一个检查点周期内,把脏页刷盘的“进度节奏”。设太高(比如 0.9),系统会拉长刷盘时间,避免 I/O 尖峰,但可能让 pg_stat_bgwriter 里 checkpoints_timed 持续上涨、buffers_checkpoint 偏高;设太低(比如 0.2),检查点一触发就猛刷,容易卡住前端写入,尤其在 SSD 以外的存储上。
实操建议:
- OLTP 场景默认用
0.9,只要磁盘吞吐够(如 200+ MB/s 持续写入能力),基本不会出问题 - 如果观察到
pg_stat_bgwriter.checkpoint_write_time占单次检查点总耗时 >30%,说明刷盘压力已影响节奏,可尝试降到0.7并配合调大max_wal_size - 切勿设为
1.0:PostgreSQL 会自动降级为0.9,且文档明确说“无实际意义”
max_wal_size 和 min_wal_size 差太多会触发意外检查点
PostgreSQL 不是等 WAL 写满 max_wal_size 才做检查点,而是在 WAL 增长到 min_wal_size + (max_wal_size - min_wal_size) * checkpoint_completion_target 附近就开始准备。如果 min_wal_size 过小(如默认 80MB)、max_wal_size 又过大(如 4GB),而业务突发写入,可能在还没达到预期 WAL 容量前,就因 checkpoint_timeout 到期或 pg_xlog(或 pg_wal)目录下活跃段文件数超限,被迫触发紧急检查点。
实操建议:
-
min_wal_size不要低于1GB(除非实例极小),避免频繁重用 WAL 段引发回收竞争 -
max_wal_size建议设为min_wal_size的 3–4 倍,例如min_wal_size = 1GB→max_wal_size = 4GB,平衡空间与检查点稳定性 - 改完必须重启或
SELECT pg_reload_conf(),但参数生效需等下一个检查点周期才体现效果
检查点参数组合导致 recovery 时 WAL 文件被提前回收
主库上 max_wal_size 设得偏小,或 checkpoint_completion_target 偏高,会导致检查点间隔拉长、WAL 循环更快。如果备库同步延迟稍大,主库可能已经把备库还没取走的 WAL 文件回收了,报错 requested WAL segment has already been removed。
实操建议:
- 流复制环境务必监控
pg_stat_replication中的replay_lsn和sent_lsn差值,超过max_wal_size * 1.5就危险 - 优先调大
max_wal_size,比调小checkpoint_timeout更安全——后者只会让检查点更密,加剧 WAL 生成压力 - 临时保底方案:在主库加
archive_command并启用归档,即使 WAL 被删也能从归档拉取
如何验证当前参数是否真起效
改完参数不能只看 SHOW 或 pg_settings,得看检查点行为本身是否改变。关键指标不在日志里,而在统计视图和文件系统。
实操建议:
- 查
SELECT * FROM pg_stat_bgwriter,重点关注checkpoints_timed(定时触发)和checkpoints_req(请求触发)比例;理想情况前者应占 85% 以上 - 用
ls -lt $PGDATA/pg_wal/ | head -20观察 WAL 文件时间戳分布,如果密集集中在最近 2–3 分钟,说明检查点太频繁 - 对比两次检查点之间
pg_control中的time字段(用pg_controldata命令读取),确认间隔是否接近checkpoint_timeout× (1 −checkpoint_completion_target)
最常被忽略的是:这些参数的效果存在“滞后性”,一次检查点周期(通常 5 分钟起)后才稳定,别刚 reload 就去翻日志找证据。










