角色定位 → 为什么需要它 → 它到底干什么 → 它和 WAL/bgwriter/后端写盘怎么分工 → 对性能和恢复有什么影响 → 怎么监控和排障”这条线讲,这样你能把 checkpointer 真正串起来。
把 checkpointer 进程 按 定义 → 存在意义 → 工作对象 → 触发机制 → 执行动作 → 与 WAL/恢复/性能的关系 → 和其他进程的边界 → 监控与调优 → 常见误区 这一条主线,系统讲透。
1)先定性:checkpointer 是什么
checkpointer 是 PostgreSQL 的一个 实例级后台进程。它的核心职责不是执行业务 SQL,也不是写 WAL,而是 在 checkpoint 发生时,把“截至某个 WAL 位置之前必须落盘的数据页”推进到数据文件中,并把 checkpoint 真正完成掉。官方文档对 checkpoint 的定义是:在 WAL 序列中的某个点,保证在此之前的信息已经反映到数据文件里,并且所有数据文件都会被 flush 到磁盘。CHECKPOINT 命令只是强制立即做一次同样的事情。(PostgreSQL)
一句话概括:
checkpointer管的是“把共享缓冲区里的脏页,在合适的时机、有节奏地、安全地落到数据文件,并形成一个新的恢复锚点”。 (PostgreSQL)
2)为什么必须有它
因为 PostgreSQL 采用 WAL 先行 的持久化模型。
事务提交时,首先要求相关 WAL 记录先持久化;而数据页本身可以稍后再写回表文件和索引文件。官方 WAL 文档明确说,数据文件里的改动只能在对应 WAL 先安全落盘之后再写。(PostgreSQL)
这就带来一个必然问题:
- 共享缓冲区里会长期积累很多 dirty page(脏页)
- 这些页迟早要刷回真实数据文件
- 系统还要定期建立一个 恢复起点
- 否则崩溃恢复需要从很久以前的 WAL 一路重放,恢复时间会越来越长。(PostgreSQL)
所以 checkpointer 的存在,本质上是为了解决三件事:
- 定期收敛脏页
- 建立新的 checkpoint/recovery 起点
- 控制恢复时间和刷盘节奏 (PostgreSQL)
3)checkpoint 到底是什么
checkpoint 不是“简单刷一次盘”,而是一个 数据库级恢复边界。
官方定义可以翻成更实战的话:
- 到某个 checkpoint 完成时
- 在该 checkpoint 之前的数据库更改
- 已经足够体现在数据文件上
- 之后如果崩溃恢复,不需要再从无限久之前开始重放 WAL,而是从更靠后的检查点开始。(PostgreSQL)
所以 checkpoint 的本质是:
给“延迟写回的数据页世界”和“顺序追加的 WAL 世界”做一次阶段性对齐。 (PostgreSQL)
4)checkpointer 真正“管”的对象是什么
它直接面对的不是 SQL,不是事务对象,而是:
- shared buffers 中的脏页
- 对应的数据文件(heap / index / FSM / VM 等)
- checkpoint 时点及其刷盘完成状态。(PostgreSQL)
也就是说,checkpointer 不是逻辑层角色,而是 存储层、页刷盘层、恢复边界层 的角色。
5)它和 WAL 的关系是什么
这个关系非常核心。
5.1 它不负责“写 WAL”
写 WAL 的主要后台角色是 walwriter,而提交路径上 backend 自己也会触发相关 WAL flush 语义。checkpointer 不是专门生产 WAL 的进程。(PostgreSQL)
5.2 但它深度依赖 WAL
因为 checkpoint 必须在 WAL 语义下成立:
只有当 WAL 先满足持久化要求,脏页刷回才是安全的。WAL 文档明确说,数据页落盘必须在相关 WAL 已持久化之后。(PostgreSQL)
5.3 checkpoint 还会反过来影响 WAL
官方文档明确指出,checkpoint 不仅昂贵在要写很多脏页,它还会导致 额外的后续 WAL 流量。一个重要原因是 full_page_writes=on 时,每个 checkpoint 之后,一个页面第一次再被修改时,会把该页的整页镜像写入 WAL,以防系统崩溃导致半页写。(PostgreSQL)
这就是为什么大家常说:
checkpoint 太频繁,不只是刷盘变多,WAL 量也会增加。 (PostgreSQL)
6)checkpointer 什么时候工作
它不是“随时把所有脏页都刷干净”的进程,它主要围绕 checkpoint 事件 工作。
官方文档给出了两类主要触发条件:
6.1 时间触发
达到 checkpoint_timeout。
也就是距离上次 checkpoint 过了一定时间,系统应当开始下一次。(PostgreSQL)
6.2 WAL 体量触发
WAL 增长逼近 max_wal_size。
官方文档说明,checkpoint 会在 max_wal_size 即将被超过时发生;因此 max_wal_size 实际上是影响 checkpoint 频率的重要参数。(PostgreSQL)
6.3 人工触发
执行 CHECKPOINT 命令会立即强制做一次 checkpoint。官方语义就是“现在立刻做,不等系统常规调度”。(PostgreSQL)
7)它一次 checkpoint 里到底做什么
把它拆成完整逻辑链,最容易理解。
第一步:确定这次 checkpoint 的边界
系统需要确定一个新的 checkpoint 目标位置,也就是“这次要把哪些此前已经 WAL 化的脏页,推进到数据文件”。这是 checkpoint 能成为恢复锚点的前提。(PostgreSQL)
第二步:把相关脏页逐步写出
checkpointer 不是瞬间把一切一起爆刷。官方 WAL 配置文档明确说明,checkpoint 活动会被 throttle(节流/摊平),目的是让 I/O 从 checkpoint 开始时就逐步进行,并在下一次 checkpoint 前完成,从而减小性能抖动。checkpoint_completion_target 正是控制“把 checkpoint 完成目标分摊到多大比例时间窗口里”的参数。(PostgreSQL)
第三步:确保这些写入真正 flush 到磁盘
checkpoint 不是只把数据交给 OS page cache 就算完。官方定义里明确要求数据文件被 flush 到 disk。(PostgreSQL)
第四步:完成 checkpoint,建立新的恢复起点
到这一步,系统才真正有了一个新的“从这里开始恢复即可”的更近锚点。恢复所需 WAL 范围因此被前推,崩溃恢复时间通常也会随之收敛。(PostgreSQL)
8)为什么它不能“越频繁越好”
很多人初学会误以为:checkpoint 越勤快越安全。
这不对。
官方文档明确指出 checkpoint 很贵,原因有两层:
- 要写出大量当前脏页
- 还会导致额外后续 WAL 流量。(PostgreSQL)
所以 checkpoint 过于频繁会带来:
- 更高的随机/混合写压力
- 更明显的 I/O 抖动
- 更高的 WAL 体积
- 更差的吞吐稳定性。(PostgreSQL)
因此 PostgreSQL 官方建议的方向是:
参数要设得足够大,避免 checkpoint 过于频繁。 (PostgreSQL)
9)为什么它也不能“拖得太久”
反过来,如果 checkpoint 太稀疏,也会有问题。
因为 checkpoint 的意义之一就是缩短崩溃恢复链路。
checkpoint 间隔过大意味着:
- 未被 checkpoint 收敛的 WAL 范围更长
- 崩溃后需要重放更多 WAL
- 恢复时间更长
- 运行期 WAL 占用也可能更高。(PostgreSQL)
所以 checkpointer 要解决的是一个平衡问题:
既不能过密导致运行期 I/O 和 WAL 成本升高,也不能过疏导致恢复链过长。 (PostgreSQL)
10)它和 background writer 的区别
这是最容易混淆的一组。
官方文档说明,background writer 是一个独立后台进程,它的职责是在系统感觉“clean buffer 可能不够”时,预先把一部分 dirty shared buffer 写回文件系统并标记为 clean,目的是降低前台 backend 自己分配新缓冲页时被迫写脏页的概率。(PostgreSQL)
所以边界是:
background writer
- 偏“日常保洁”
- 目标是准备更多 clean buffer
- 重点是缓解前台进程分配 buffer 时的写压力
- 不是 checkpoint 的最终完成者。(PostgreSQL)
checkpointer
- 偏“阶段性大收口”
- 目标是完成 checkpoint
- 重点是形成恢复边界,保证 checkpoint 语义成立
- 要求相关页最终 flush 到盘。(PostgreSQL)
一句话记忆:
bgwriter 关心“平时别让前台太难受”,checkpointer 关心“checkpoint 必须真正完成”。 (PostgreSQL)
另外,PostgreSQL 官方 feature matrix 还提到,历史上 checkpoint 职责曾经在 bgwriter 里,后来拆成独立的 checkpointer 进程。(PostgreSQL)
11)它和 walwriter 的区别
walwriter 管的是 WAL buffer/WAL file 这条线;checkpointer 管的是 shared buffers → data files 这条线。(PostgreSQL)
更直白地说:
walwriter:把日志世界往前推checkpointer:把数据页世界往前推
二者共同作用,才让 PostgreSQL 的“WAL 先行、数据页后刷”模式成立。(PostgreSQL)
12)它和普通 backend 的关系
普通 backend 在很多情况下也会自己写脏页,尤其当要复用 buffer、可用 clean buffer 不足时。
官方 bgwriter 文档就明确说,bgwriter 的目的之一是减少 backend 自己被迫执行写操作的概率。(PostgreSQL)
因此三者关系是:
- backend:必要时也会写页,主要以完成当前业务为先
- bgwriter:平时预写一些脏页,减轻 backend 压力
- checkpointer:在 checkpoint 事件上负责最终收口和完成。(PostgreSQL)
13)checkpointer 对性能的影响
这个模块之所以重要,就是因为它几乎直接碰到性能最敏感的几个面。
13.1 I/O 峰值
checkpoint 要写很多脏页,如果刷盘过猛,会形成明显 I/O 峰值。官方文档因此强调 checkpoint activity 要节流,并让 checkpoint_completion_target 把写入尽量摊平。(PostgreSQL)
13.2 延迟抖动
checkpoint 过于集中时,前台读写容易与大量刷盘竞争磁盘带宽和 IOPS,导致 RT 抖动,尤其在机械盘、云盘、共享存储、IOPS 限额环境里更明显。这个结论直接来自 checkpoint 是昂贵且需大量 I/O 的官方描述。(PostgreSQL)
13.3 WAL 放大
checkpoint 太勤会让更多页面更频繁地触发 checkpoint 后首次修改,从而增加 full-page image 带来的 WAL 体积。官方 full_page_writes 说明已经给出机制基础。(PostgreSQL)
13.4 崩溃恢复时间
checkpoint 间隔越长,通常潜在 WAL 重放区间越长;恢复更久。checkpoint 间隔越短,恢复可能更快,但运行期开销更高。(PostgreSQL)
所以 checkpointer 的调优,本质上是在平衡:
运行期写放大 / 抖动 / WAL 体积 和 崩溃恢复时间 / WAL 积压。 (PostgreSQL)
14)它和 full_page_writes 的关系为什么常被一起讲
因为 full_page_writes=on 时,每个 checkpoint 之后,一个页面第一次被修改,会把整页内容写进 WAL。官方文档明确说明这是为了防止系统崩溃时页面只写了一半,导致页内容新旧混杂。(PostgreSQL)
这意味着:
- checkpoint 越频繁
- “checkpoint 后第一次改页”的机会越多
- full-page image 越多
- WAL 体积可能越大。(PostgreSQL)
这也是为什么很多性能分析里,checkpoint 和 WAL volume 要一起看。
15)在 standby 上它还有什么角色
在恢复/备库环境里,官方 WAL 配置文档提到 restartpoint 的概念,并且 pg_stat_checkpointer 中还有 restartpoints_done、restartpoints_req 等统计。restartpoint 可以理解为恢复过程中的“checkpoint 对应物”。(PostgreSQL)
所以在 standby 上,checkpointer 不只是“主库 checkpoint 逻辑的旁观者”,它还参与恢复侧的阶段性收口。
这也是为什么 PostgreSQL 现在单独提供了 pg_stat_checkpointer 视图来监控这一类行为。(PostgreSQL)
16)怎么监控 checkpointer
16.1 主要看哪个统计视图
当前 PostgreSQL 已经有单独的 pg_stat_checkpointer 视图,官方累计统计文档明确列出了它。历史上 checkpointer 统计混在 pg_stat_bgwriter,后来拆分出来。(PostgreSQL)
16.2 重点看什么
从官方资料可以抓住这些核心方向:
num_timed:定时触发的 checkpoint 数num_requested:因请求/压力触发的 checkpoint 数write_time:checkpoint 写阶段耗时sync_time:checkpoint 同步落盘耗时buffers_written:checkpoint 期间写出的 buffer 数- standby 场景看
restartpoints_done/restartpoints_req。(PostgreSQL)
16.3 这些指标怎么解释
num_requested很高:常说明 checkpoint 不是按平稳时间窗口来,而是被 WAL 体量或其他请求推着跑,常见于max_wal_size太小或写入高峰太猛。(PostgreSQL)write_time/sync_time高:说明 checkpoint 刷盘和最终同步代价大,存储压力或抖动明显。(PostgreSQL)buffers_written很大:说明 checkpoint 收口时背负的脏页量大。(PostgreSQL)
17)相关配置参数,哪些最重要
checkpoint_timeout
控制最长多久做一次常规 checkpoint。(PostgreSQL)
max_wal_size
控制 WAL 增长到什么程度前后要触发 checkpoint。不是绝对硬上限,但会强烈影响 checkpoint 频率。(PostgreSQL)
checkpoint_completion_target
控制把 checkpoint 的刷盘尽量铺满多大比例的周期;默认 0.9,意味着尽量把 I/O 平摊到整个间隔的大部分时间里。(PostgreSQL)
checkpoint_warning
官方建议可作为 sanity check;如果经常出现“两个 checkpoint 间隔太近”的警告,说明你的 checkpoint 参数可能过激。(PostgreSQL)
这些参数背后的原则不是“背数值”,而是理解:
checkpoint 的频率、强度、平滑程度,主要由“时间阈值 + WAL 体量阈值 + 写入摊平策略”共同决定。 (PostgreSQL)
18)典型现象怎么从 checkpointer 角度理解
现象一:系统每隔几分钟就卡一下
很可能是 checkpoint 过于集中,刷盘不平滑,导致 I/O 峰值和延迟抖动。先看 checkpoint 频率、write_time、sync_time、日志里的 checkpoint 信息。官方文档明确指出 checkpoint 可能造成明显 I/O 负载。(PostgreSQL)
现象二:WAL 涨得特别快
不一定只是业务写入本身,也可能有 checkpoint 过频 + full_page_writes 带来的 WAL 放大。(PostgreSQL)
现象三:崩溃恢复很慢
可能 checkpoint 间隔太长,恢复要重放更多 WAL。(PostgreSQL)
现象四:前台 backend 经常自己写脏页
可能 clean buffer 供给不足,bgwriter 不够积极,或整体写入压力太大;这不全是 checkpointer 的锅,但说明“平时保洁”和“阶段收口”都可能不理想。(PostgreSQL)
19)最常见的误区
误区一:checkpoint 就是把所有内存都刷盘
不准确。它关心的是 形成 checkpoint 语义所需的脏页集合和落盘完成状态,不是“把所有共享内存无脑清空”。(PostgreSQL)
误区二:checkpointer 平时负责所有脏页写回
不对。平时还有 bgwriter 和 backend 本身参与写脏页;checkpointer 是 checkpoint 事件上的主角。(PostgreSQL)
误区三:checkpoint 越勤越安全、越好
不对。太勤会显著增加 I/O 和 WAL 成本。(PostgreSQL)
误区四:只要 max_wal_size 大就一定更好
也不绝对。它可以减少 checkpoint 频率,但也会拉长潜在恢复链和扩大 WAL 占用。(PostgreSQL)
误区五:只看 pg_stat_bgwriter 就够了
当前版本里 checkpointer 已有独立视图 pg_stat_checkpointer,应单独观察。(PostgreSQL)
20)把 checkpointer 的系统逻辑压缩成一条线
你可以这样记整条链:
前台事务修改页
→ 页先在 shared buffers 里变脏
→ WAL 先行保证持久化语义
→ 脏页可以延后写数据文件
→ 系统定期或因 WAL 压力触发 checkpoint
→ checkpointer 在一个时间窗口内平滑地写出并 flush 相关脏页
→ checkpoint 完成,建立新的恢复边界
→ 之后崩溃恢复只需从更近的 checkpoint 开始
这条链就是 checkpointer 的核心存在意义。(PostgreSQL)
21)最适合面试的标准答案
checkpointer是 PostgreSQL 的实例级后台进程,负责在 checkpoint 发生时把共享缓冲区中与该 checkpoint 相关的脏页有节奏地写回并 flush 到数据文件,最终建立新的恢复边界。它不负责写 WAL,而是与 WAL 机制配合工作:WAL 先行保证一致性,checkpointer 再推进数据页世界向数据文件收敛。它的核心价值是平衡三件事:运行期刷盘开销、WAL 放大、以及崩溃恢复时间。它和 bgwriter 的区别在于,bgwriter偏向平时预写脏页、为 backend 准备 clean buffer;checkpointer 则负责 checkpoint 的最终完成。监控上应重点看pg_stat_checkpointer、checkpoint 频率、write/sync 时间,以及checkpoint_timeout、max_wal_size、checkpoint_completion_target这些参数。 (PostgreSQL)
补这 8 个点。把这些补齐,checkpointer 这一块就比较圆了。
1. 它的“完成条件”要再钉死
很多人只记得“写脏页”,但 checkpoint 真正的完成条件更严格:
不是“把页发给 OS”就完了,而是 相关数据文件要被 flush 到磁盘,这样这个 checkpoint 才能成为新的恢复边界。CHECKPOINT 命令文档对这一点说得很明确。(PostgreSQL)
2. 它的核心价值是“两头平衡”
前面已经讲了性能和恢复,但还可以再压缩成一个更适合面试的表述:
- checkpoint 太频繁:运行期 I/O 和 WAL 放大更明显
- checkpoint 太稀疏:崩溃恢复要重放更多 WAL,恢复时间更长
所以 checkpointer 不是单纯“刷盘进程”,而是 运行期吞吐稳定性 和 故障后恢复时间 之间的平衡器。官方 WAL 配置文档就是按这个逻辑解释 checkpoint 成本与收益的。(PostgreSQL)
3. max_wal_size 不是“纯 WAL 参数”
这个很容易漏。
虽然名字看起来像 WAL 容量参数,但它实际上强烈影响 checkpoint 频率,因为系统会在即将超过 max_wal_size 时触发 checkpoint。也就是说,它既是 WAL 空间参数,也是 checkpoint 节奏参数。(PostgreSQL)
4. checkpoint_completion_target 的意义要更明确
它不是“让 checkpoint 更慢”,而是 把这次 checkpoint 的写盘尽量摊平到整个 checkpoint 周期的大部分时间里,避免集中刷盘造成 I/O 尖峰。官方文档明确说 checkpoint 写脏页会被 spread over a period of time,而这个 period 由 checkpoint_completion_target 控制。(PostgreSQL)
5. 要补上 checkpoint_warning 和 log_checkpoints
这两个很实用。checkpoint_warning 可以帮助你发现 checkpoint 是否发生得过于频繁;log_checkpoints 则适合在日志里直接看到 checkpoint 的耗时、写盘量和触发原因。前者在官方 WAL 配置文档中被明确提到可用于发现 max_wal_size 过小等问题。(PostgreSQL)
6. 要补上和 shared_buffers 的联动
shared_buffers 变大,不只是缓存更多页,也通常意味着单次 checkpoint 可能要面对更多脏页,所以官方资源配置文档明确提醒:较大的 shared_buffers 往往需要相应增大 max_wal_size,以便把大量新写入/修改数据的刷盘过程摊到更长时间里。这个联动很重要。(PostgreSQL)
7. 要补 standby 上的 restartpoint
如果面试官追到主备或恢复,单讲主库 checkpoint 不够完整。
在 standby/恢复侧,对应概念是 restartpoint。它和 checkpoint 是同一类“恢复收口点”思路,只是发生在恢复流程里。当前官方监控与 WAL 配置文档都把 restartpoint 单独列出来。(PostgreSQL)
8. 监控入口要从“只看 bgwriter”升级为“单看 checkpointer”
现在更推荐直接看 pg_stat_checkpointer,而不是把 checkpointer 统计和 bgwriter 混在一起理解。当前官方监控文档已经把 cumulative statistics 拆得更清楚。(PostgreSQL)
最值得补上的一句总结是:
checkpointer不只是“刷脏页的后台进程”,而是通过定期完成 checkpoint,把共享缓冲区里的脏页世界与 WAL 恢复边界重新对齐,并在运行期开销、WAL 放大、恢复时间之间做平衡。它的节奏主要受checkpoint_timeout、max_wal_size、checkpoint_completion_target共同塑形。 (PostgreSQL)
你要的话,我下一条可以直接把 “面试里 checkpointer 最容易被追问的 20 个点” 给你列成问答版。
了解 www.876873.xyz 的更多信息
订阅后即可通过电子邮件收到最新文章。
检查点进程:等您坐沙发呢!