PG 中最重要两个进程是守护进程 postgres server process 和服务进程 postgres backend process。
PG 守护进程的名称有一段演变历史。在8.2版本之前称为 postmaster;此后社区将其更名为postgres,同时保留postmaster符号链接以确保兼容性;而在2023年发布的16版本中,"General incompatibilities"明确记载已移除postmaster二进制文件的符号链接。[1][2]
除了两个核心进程外,还包括Background writer、Checkpointer、WAL writer、Autovacuum、Statistics collector、Log writer、Archiver以及复制等其他相关进程。它的进程结构图如下图1.

图1:PG 进程结构,来自interdb.jp [3]
Postgres server process
Server 进程守护进程负责数据库实例的启动、关闭、崩溃恢复、监听客户端连接以及启动和管理一系列后台维护进程,比如Checkpointer、Autovacuum等。
比如当守护进程监听到客户端请求并有新的连接到来时,fork 出一个专属的 backend 进程, backend 进程负责解析 SQL、生成执行计划并最终执行查询或更新。所有 backend 共享一块公共的内存区域(Shared memory),其中包含 Shared buffers、WAL buffers 等,用来在不同进程之间交换数据和保持一致性。
更多守护进程的信息,可以参考文模连接[4].
Postgres backend process
Backend 进程用于接收、执行客户端发送的命令,并调用底层存储、事务管理、索引等功能模块,完成客户端的各种数据库操作,并返回执行结果;除此之外,后端进程也会参与其他进程协作。比如后端进程本身不会长期刷盘,而是把脏页标记后,由 background writer、checkpoint 等进程负责最终落盘。
一个连接结束,backend 进程退出,所有专属于该连接的资源都会释放。但如果使用了PgBouncer 连接池,backend 进程会存活更久,资源释放则取决于不同连接池的工作原理。
Background Writer
Background Writer 的主要任务是将 shared buffers 中的脏页异步周期性写入数据文件,通过持续、平滑地将缓冲区中的数据刷盘,有效平衡了数据的持久性和写入性能。主要相关参数是[5]:
bgwriter_delay = 200msbgwriter_lru_maxpages = 100bgwriter_lru_multiplier = 2.0bgwriter_flush_after = 512kB
bgwriter_delay
backgroud writer 进程连续两次flush数据之间的时间的间隔。默认值是200,单位是毫秒。
bgwriter_lru_maxpages
backgroud writer进程每次写的最大数据量,默认值是100,单位buffers。
bgwriter_lru_multiplier
bgwriter_flush_after
是指定后台写入进程在累计写入一定量数据后,强制将操作系统缓存中的数据刷写到磁盘的阈值。Linux 上的默认值为 512kB,其他地方的默认值为 0。
Checkpoint
Checkpoint 负责生成数据库的检查点,确保在宕机或崩溃恢复时,系统能回到一致性的状态。它会将 shared buffers 中的所有脏页与 WAL 日志同步刷盘,从而保证数据文件和 WAL 的对应关系一致。检查点机制避免了在恢复过程中需要从很早的日志位置开始回放,缩短了恢复时间,同时保证了数据库事务持久化的可靠性。主要相关参数是:
checkpoint_timeout = 5mincheckpoint_completion_target = 0.9max_wal_size = 1GB
checkpoint_timeout
两次检查点之间的最大时间间隔,单位是秒。
checkpoint_completion_target
控制着检查点完成的速度,它决定了在两次检查点之间,系统应该花多长时间来完成一个检查点操作,值是0 到1 之间的浮点数,表示检查点完成时间占两次检查点间隔时间的比例
max_wal_size
WAL 文件允许的最大大小,超过后触发检查点。这不是严格限制,在特殊情况下,例如高负载、失败的 archive_command 或高 wal_keep_size 设置,WAL 大小可能会超过 max_wal_size 。
WAL Writer
WAL Writer 进程负责把 WAL 缓冲区中的日志数据定期写入磁盘文件,确保事务持久性。与每个事务自己写 WAL 的方式相比,集中写入可以显著减少磁盘写次数,降低 I/O 压力。这样既保证了事务提交后的数据安全性,又通过批量化写盘优化了性能,是数据库在高并发场景下维持稳定吞吐量的重要保障。
wal_writer_delay = 200mswal_writer_flush_after = 1MB
wal_writer_delay
WAL 写进程的唤醒间隔,单位毫秒。
wal_writer_flush_after
控制 WAL writer 每写多少字节后强制 fsync 刷新。如果未指定单位,则将其视为 WAL 块,即 XLOG_BLCKSZ 字节,通常为 8kB。默认值为 1MB 。
Autovacuum
Autovacuum 进程主要负责自动清理表死元组,防止表无限膨胀。它在后台按需运行,无需人工干预,保证了表空间的可控和查询效率的稳定。
关于Autovacuum 更多信息,在上一篇文章中有详细介绍,有兴趣的同学可以阅读跟着问题学习PG2:vacuum 前世今生
Log Writer
Log Writer 将数据库运行中的日志记录写入磁盘文件,方便管理员进行诊断和审计,记录系统运行日志,比如错误信息、慢查询、连接情况等,不包括WAL日志。通过及时刷盘,Log Writer 确保了系统运行日志的完整性和实时性,为定位问题、优化 SQL、追溯异常提供了可靠依据。相关参数有:
logging_collector = offlog_directory = loglog_filename = postgresql-%Y-%m-%d_%H%M%S.loglog_rotation_age = 24hlog_rotation_size = 10MB
logging_collector
是否启用日志收集进程,默认off
log_directory
日志文件存放目录。
log_filename
日志文件命名规则。
log_rotation_age
当 logging_collector 启用时,此参数确定单个日志文件的最大使用时间,之后将创建新的日志文件,默认1天。
log_rotation_size
当 logging_collector 开启时,此参数决定单个日志文件的最大大小。当向日志文件中写入这么多数据后,将创建新的日志文件,默认10MB
Archiver
Archiver 进程在数据库启用 WAL 归档模式时启动,其任务是将已完成的 WAL 文件复制到长期存储中。归档日志为时间点恢复(PITR)和主备复制提供了必要保障。即使主库发生故障,通过归档的 WAL 文件,数据库可以恢复到任意指定时间点。对于需要高可用和数据安全的生产环境,Archiver 是关键的数据保护工具。
archive_mode = offarchive_command = ''archive_timeout = 1min
archive_mode
是否启用 WAL 归档,默认OFF,可以设置on 和 always
archive_command
执行归档的命令,默认值是一个空字符串, “%p” 表示将要归档的wal文件包含完整路径的信息的文件名,“%f” 代表不包含路径信息的wal文件的文件名
archive_timeout
即使未填满 WAL 文件,也强制归档的最大时间间隔,默认是0。建议改成每分钟,确保即使在数据库活动较少的情况下,也能定期触发 WAL 日志的归档操作,从而减少未归档数据的积累。
根据上面介绍,整理出PG 主要进程表格,如表1。
表1:PG 主要进程介绍
在linux 操作系统中,我们可以通过ps 命令查看PG的进程。在以下示例中,有一个 postgres 守护进程,ID 为 6541,两个后端进程分别是8412 和 8482,以及其他后台进程。
$ pstree -p 6541-+= 00001 root /sbin/launchd\-+= 06541 postgres /usr/local/pgsql/bin/postgres -D data|--= 06542 postgres postgres: io worker 0|--= 06543 postgres postgres: io worker 1|--= 06544 postgres postgres: io worker 2|--= 06545 postgres postgres: checkpointer|--= 06546 postgres postgres: background writer|--= 06548 postgres postgres: walwriter|--= 06549 postgres postgres: autovacuum launcher|--= 06550 postgres postgres: walsummarizer|--= 06551 postgres postgres: logical replication launcher|--= 08412 postgres postgres: postgres testdb [local] idle|--= 08482 postgres postgres: postgres testdb [local] idle in transaction
08412 postgres: postgres testdb [local] idle08482 postgres: postgres testdb [local] idle in transaction
这两个是服务进程,idle表示空闲,idle in transaction表示事务未提交。I/O Workers(PIDs 06542-06544)这三个进程是PG 18 新增加的通过异步I/O操作提升系统并发能力进程。
了解 PG 的进程模型,除了更清楚每个连接、查询和后台任务是怎么被调度和执行以外,在实际运维中,遇到 CPU 高、IO 卡、性能抖动或者阻塞时,也能知道问题出在哪个进程,方便调优连接池、内存和事务策略,做到有的放矢地提升性能和稳定性,实现数据库运维的知行合一。下面通过具体的生产案例,从进程角度解决。
Checkpoint 过于频繁
Checkpoint 是将共享缓冲区中的脏页写回磁盘的过程,这可能会带来大量磁盘 I/O,从而引起数据库 TPS下降,但这是在保证数据持久性与写入性能之间提供了平衡,也是几乎所有关系型数据库的通用设计。
查看PG 日志,看到类似下面信息:
LOG: checkpoint starting: timeLOG: checkpoint complete: wrote 1024 buffers (8.0%); 0 WAL file(s) added, 0 removed, 2 recycled; write=150.123 s, sync=2.456 s, total=152.789 s; sync files=100, longest=0.200 s, average=0.024 s
如果你在日志里频繁看到 checkpoint starting,而且间隔明显小于 checkpoint_timeout(默认 5min),说明 checkpoint 触发得太频繁。触发原因可能是大量写入操作导致脏页积压,max_wal_size 设置过小,WAL 快速膨胀导致频繁触发,需要讨论checkpoint_timeout 、checkpoint_completion_target 等参数是否设置合理。
Autovacuum 导致抖动
Autovacuum 是用于自动清理表中的死元组、回收空间并更新统计信息,防止表膨胀和查询性能下降。在高并发或大表环境下,Autovacuum 有时会触发大量 I/O 和 CPU 消耗,尤其是在清理大型表或执行复杂索引维护时。这种突然启动的资源占用会与业务查询争用 CPU 和磁盘,导致短时间内 TPS 下降或响应变慢,出现性能抖动。
查看日志,看到类似下面信息:
LOG: automatic vacuum of table "public.orders": index scans: 1pages: 0 removed, 2000 remain, 1500 skipped due to pins...tuples: 50000 removed, 200000 remain
也可以从 pg_stat_activity 里看到 autovacuum worker 占用资源。
为缓解这种抖动,可以通过调整 Autovacuum 参数。比如降低 autovacuum_vacuum_cost_limit 和 autovacuum_vacuum_cost_delay,让清理过程更平滑;针对大表,可采用分区表或手动分批 VACUUM;同时,合理设置 autovacuum_naptime 和并发 worker 数量,使 Autovacuum 在业务低峰期运行,从而减少对正常事务的影响,保持系统稳定。
WAL Archiver 堵塞事务
WAL Archiver 是负责将 WAL(Write-Ahead Log)日志归档到外部存储,如 NFS、S3 或备份服务器,以保证数据库可以进行 PITR(时间点恢复)。当归档操作失败或速度跟不上 WAL 生成速度时,导致 WAL 文件在 pg_wal 目录中堆积,从而阻塞前端事务提交。
查看日志,看到类似下面信息:
LOG: archive command failed with exit code 1DETAIL: The failed archive command was: cp pg_wal/000000010000000A000000FB /backup/pg_wal/WARNING: archiving transaction log file "000000010000000A000000FB" failed too many times, will try again later
这种堵塞通常由网络延迟、外部存储不可用、权限问题或归档命令脚本错误引起。为解决此问题,可以优化归档目标的性能,确保网络稳定和权限正确,同时对归档命令脚本进行异常处理和重试机制。
可通过监控pg_stat_archiver、配置合理的wal_keep_size、调整归档速率预防 WAL 堆积;清理归档目录空间,对pg_wal目录大小设置告警,检查archive_status文件状态,以维持数据库正常写入性能和高可用性。
实际上,Checkpoint、Autovacuum、WAL Arch 引发的问题看似都能从日志找到线索,深层次的是反映了数据库架构层面的资源管理问题。Checkpoint 受 WAL 写入和脏页压力影响,Autovacuum 抖动源于死元组清理与业务 I/O 冲突,Archiver 堵塞则暴露备份链可靠性问题。理解这些进程机制,能更准确、快速地解决问题。
本文主要介绍 PG 相关进程含义、作用,以及在实际运维中如何根据相关现象,从数据库进程角度解释问题原因,并给出可靠的解决方案。
参考
1、https://www.postgresql.org/docs/release/8.2.0/
2、https://www.postgresql.org/docs/release/16.0/
3、https://www.interdb.jp/pg/pgsql02/01.html
4、https://www.crunchydata.com/blog/postgres-postmaster-file-explained5、https://www.postgresql.org/docs/14/runtime-config-wal.html
作者介绍
司马辽太杰,10余年数据库架构和运维管理经验,擅长常见关系型、NoSQL、MPP 等类型数据库。业余热爱历史、足球,读点闲书。欢迎关注个人公众号“程序猿读历史”。如需联系,可从关注公众号,在公众号对话窗口中扫码添加好友。感谢您的支持!

