
好的,我们来详细拆解 PostgreSQL 的进程结构。理解其多进程架构对于数据库管理、性能调优和故障排查至关重要。
核心概念:多进程模型
与 MySQL 等采用多线程模型的数据库不同,PostgreSQL 使用传统的 多进程模型。这意味着数据库服务器的不同功能由独立的操作系统进程来完成。这种设计提供了更好的隔离性(一个进程崩溃不一定影响整个实例)和在某些场景下的稳定性,但也带来了更高的上下文切换开销。
主要进程分类及详解
-
主守护进程 (Postmaster / Main Server Process)
- 作用功能:
- 数据库实例的总管家,是启动 PostgreSQL 后第一个运行的进程。
- 监听并接受客户端连接请求(在
postgresql.conf中配置的listen_addresses和port)。 - 负责启动、管理和终止所有其他 PostgreSQL 进程(后台辅助进程和客户端后端进程)。
- 管理共享内存区域(包括共享缓冲区、WAL 缓冲区等)。
- 执行数据库的启动、关闭、恢复等核心操作。
- 处理信号(如 SIGHUP 重载配置,SIGTERM 优雅关闭等)。
- 进程出问题的影响:
- 最严重! 如果 Postmaster 进程崩溃或被杀死,整个数据库实例将立即不可用。
- 所有现有连接会被强制断开。
- 新的连接无法建立。
- 所有后台进程也会随之终止。
- 排查命令:
ps aux | grep postgres或ps -ef | grep postgres: 查看 Postmaster 进程是否存在及其 PID。通常命令类似/usr/lib/postgresql/14/bin/postgres -D /var/lib/postgresql/14/main ...pg_ctl status -D <你的数据目录>: 检查数据库实例的运行状态。tail -f <你的日志文件>(通常在log_directory配置项下): 查看数据库日志,这是诊断 Postmaster 启动失败、崩溃等问题的最重要依据。日志会记录详细的错误原因(如配置错误、端口冲突、内存不足、权限问题、数据损坏等)。netstat -tulnp | grep <pg_port>: 检查 Postmaster 是否在监听配置的端口。systemctl status postgresql(如果使用 systemd): 检查服务状态。
- 作用功能:
-
后台辅助进程 (Background Utility Processes)
- 这些进程由 Postmaster 启动,执行数据库内部维护任务,与特定客户端连接无关。
- 常见后台进程及其作用、影响、排查:
- a. Logger (Syslogger - 可选但强烈推荐启用)
- 作用功能: 负责捕获所有其他 PostgreSQL 进程产生的日志消息,并将其写入日志文件。如果未配置
logging_collector = on,日志会直接写到 stderr(通常由启动脚本重定向到文件或 systemd/journald 捕获)。 - 进程出问题的影响:
- 如果 Syslogger 崩溃且配置了
logging_collector=on,日志可能无法写入文件(但可能缓冲在内存直到满),影响问题诊断。 - 如果 stderr 未正确重定向且 Syslogger 未启用,日志会丢失。
- 如果 Syslogger 崩溃且配置了
- 排查命令:
ps aux | grep postgres | grep logger: 查找 Syslogger 进程。- 检查
log_directory下的日志文件是否在持续更新 (tail -f). - 检查
postgresql.conf中logging_collector,log_destination,log_directory,log_filename等配置是否正确。
- 作用功能: 负责捕获所有其他 PostgreSQL 进程产生的日志消息,并将其写入日志文件。如果未配置
- b. Checkpointer (检查点进程)
- 作用功能:
- 定期或在特定条件(如 WAL 写满、手动执行
CHECKPOINT)下触发检查点。 - 将共享缓冲区 (Shared Buffers) 中的所有脏页(被修改过的数据页)刷新到磁盘的数据文件中。
- 更新控制文件,记录检查点完成的位置(用于崩溃恢复的起点)。
- 通知 Background Writer 可以清理旧缓冲区。
- 定期或在特定条件(如 WAL 写满、手动执行
- 进程出问题的影响:
- 极其严重! 如果 Checkpointer 挂掉,Postmaster 会检测到并导致整个实例崩溃重启。因为脏页无法及时刷盘,WAL 会持续增长,崩溃恢复时间会变得非常长(需要重放大量 WAL),磁盘 I/O 压力可能剧增。最终可能导致磁盘空间耗尽或恢复失败。
- 排查命令:
ps aux | grep postgres | grep checkpointer: 确认进程存在。tail -f <日志文件>: 检查是否有关于 Checkpointer 的错误或警告(如频繁的检查点、I/O 错误)。SELECT * FROM pg_stat_bgwriter;: 查看检查点统计信息 (checkpoints_timed,checkpoints_req,buffers_checkpoint,buffers_clean,maxwritten_clean)。checkpoints_req过多可能表明配置不当或 I/O 瓶颈。SHOW checkpoint_timeout; SHOW max_wal_size; SHOW min_wal_size;: 检查检查点相关配置。
- 作用功能:
- c. Background Writer (后台写进程)
- 作用功能:
- 持续地将共享缓冲区中的部分脏页(特别是最近最少使用的脏页)刷新到磁盘。
- 目的是在 Checkpointer 需要执行大规模刷盘之前,分担 I/O 压力,平滑写入操作。
- 也负责执行一些异步清理任务(如将
fsync请求排队)。
- 进程出问题的影响:
- 如果 Background Writer 挂掉,Postmaster 同样会检测到并导致整个实例崩溃重启。原因与 Checkpointer 类似,脏页积压会增加 Checkpointer 的压力和崩溃恢复时间。
- 排查命令:
ps aux | grep postgres | grep writer: 确认进程存在。tail -f <日志文件>: 检查错误。SELECT * FROM pg_stat_bgwriter;: 关注buffers_backend,buffers_clean,maxwritten_clean,buffers_backend_fsync。buffers_backend过高可能表明 Background Writer 不够有效,后端进程被迫自己刷盘。SHOW bgwriter_delay; SHOW bgwriter_lru_maxpages; SHOW bgwriter_lru_multiplier;: 检查相关配置。
- 作用功能:
- d. WalWriter (WAL 写进程 - 通常有多个)
- 作用功能:
- 将 WAL (Write-Ahead Log) 缓冲区 中的内容刷新到磁盘上的 WAL 文件 (在
pg_wal目录)。 - 这是确保事务持久性 (Durability) 的关键机制。事务提交前,其产生的 WAL 记录必须已落盘 (
WALflushed to disk)。 - 从 PostgreSQL 9.4 开始,可以有多个 WalWriter 进程(通过
wal_writer_delay和wal_writer_flush_after间接影响,高并发写入时可能自动产生辅助写进程)。
- 将 WAL (Write-Ahead Log) 缓冲区 中的内容刷新到磁盘上的 WAL 文件 (在
- 进程出问题的影响:
- 极其严重! 如果所有 WalWriter 进程都失效,任何需要写 WAL 的操作(几乎所有的 DML 和部分 DDL)都会挂起或超时失败。因为 WAL 缓冲区无法刷盘,提交无法完成,最终会导致连接堆积、实例无响应甚至崩溃。
- 排查命令:
ps aux | grep postgres | grep walwriter: 确认主 WalWriter 进程存在。tail -f <日志文件>: 查找 WAL 写入错误或 I/O 错误。SELECT * FROM pg_stat_wal;(较新版本) 或pg_stat_get_wal_writers()(函数): 查看 WAL 写入统计。ls -l $PGDATA/pg_wal/: 检查 WAL 文件是否在生成和归档(如果配置了归档)。观察文件大小和修改时间。SHOW wal_writer_delay; SHOW wal_writer_flush_after; SHOW commit_delay; SHOW commit_siblings;: 检查相关配置。
- 作用功能:
- e. Autovacuum Launcher (自动清理启动器)
- 作用功能:
- 本身不执行清理任务。
- 定期检查数据库中的表是否需要执行
VACUUM或ANALYZE。 - 如果需要,它会启动 Autovacuum Worker 进程 来实际执行这些维护操作。
- 进程出问题的影响:
- 如果 Launcher 挂掉,不会导致实例崩溃。
- 但会导致没有新的 Autovacuum Worker 被启动。
- 后果:表膨胀(死元组堆积,占用大量空间,降低查询效率)、过时的统计信息(导致优化器生成劣质执行计划)、事务 ID 回绕风险(极严重,但现代版本通过预防性 autovacuum 极大降低了此风险)。
- 排查命令:
ps aux | grep postgres | grep autovacuum | grep launcher: 确认进程存在。SHOW autovacuum;: 确认自动清理已启用 (on)。SELECT schemaname, relname, n_dead_tup, last_autovacuum FROM pg_stat_all_tables WHERE n_dead_tup > 0 ORDER BY n_dead_tup DESC;: 查看死元组数量多且长时间未被清理的表。SELECT * FROM pg_stat_activity WHERE backend_type LIKE '%autovacuum%';: 查看当前是否有正在运行的 Autovacuum Worker。如果 Launcher 挂了,长时间不会有新的 Worker 出现。- 检查日志中是否有 Autovacuum Launcher 的错误。
- 作用功能:
- f. Autovacuum Worker (自动清理工作进程)
- 作用功能:
- 由 Autovacuum Launcher 启动。
- 负责对具体的表执行
VACUUM(清理死元组,冻结旧事务 ID,更新可见性映射)、ANALYZE(更新统计信息)或VACUUM FREEZE操作。 - 可以同时存在多个 Worker (由
autovacuum_max_workers控制)。
- 进程出问题的影响:
- 单个 Worker 崩溃通常不会导致实例崩溃。Launcher 会记录错误并重试该表的清理。
- 影响范围通常是该 Worker 正在处理的特定表:该表的清理失败,死元组继续堆积,统计信息未更新。
- 如果多个 Worker 频繁崩溃,可能表明存在更普遍的问题(如磁盘错误、内存损坏、表损坏),最终会导致表膨胀和性能问题累积。
- 如果
autovacuum_max_workers设置过小且 Worker 被长时间运行的事务或锁阻塞,会导致其他需要清理的表排队,同样造成表膨胀。
- 排查命令:
ps aux | grep postgres | grep autovacuum | grep worker: 查看正在运行的 Worker 进程及其命令行参数(通常能看到它正在处理的数据库和表)。SELECT * FROM pg_stat_activity WHERE backend_type LIKE '%autovacuum%';: 查看 Worker 状态、正在执行的查询、是否被阻塞。SELECT * FROM pg_stat_progress_vacuum;: 查看正在执行的 VACUUM 操作的详细进度。tail -f <日志文件>: 查找特定 Autovacuum Worker 的崩溃报告或错误信息,通常会指出是哪个表出了问题。- 检查上面提到的
pg_stat_all_tables视图。
- 作用功能:
- g. Archiver (归档进程 - 可选,需要配置归档)
- 作用功能:
- 当启用 WAL 归档 (
archive_mode = on) 时,此进程会被启动。 - 负责将已填满的 WAL 段文件 (
pg_wal目录下的文件) 复制到配置的归档位置(通过archive_command指定,如cp,rsync, 或专用备份工具命令)。
- 当启用 WAL 归档 (
- 进程出问题的影响:
- 如果 Archiver 进程失败,不会导致实例崩溃。
- 但会导致 WAL 文件无法成功归档。
- 后果:
pg_wal目录会持续积累 WAL 文件,可能耗尽磁盘空间,导致数据库停止所有写操作(因为无法生成新的 WAL)。- 破坏基于 WAL 归档的备份策略(如 PITR, 持续归档备份),无法恢复到最新时间点或创建新的基础备份。
- 排查命令:
ps aux | grep postgres | grep archiver: 确认进程存在。SHOW archive_mode; SHOW archive_command;: 确认归档已启用且命令正确。SELECT * FROM pg_stat_archiver;: 最重要! 查看归档状态:last_archived_wal: 最后成功归档的 WAL 文件名。last_archived_time: 最后成功归档的时间。last_failed_wal,last_failed_time: 最后归档失败的 WAL 文件和时间。failed_count: 连续失败次数。
ls -l $PGDATA/pg_wal/: 查看目录中是否存在大量.ready文件(表示需要归档但尚未归档的 WAL)和.done文件(表示已归档)。堆积的.ready文件是问题标志。tail -f <日志文件>: 查看 Archiver 进程执行archive_command的具体输出和错误信息(需要确保logging_collector启用且日志级别足够)。
- 作用功能:
- h. Stats Collector (统计信息收集器)
- 作用功能:
- 收集数据库的性能统计信息和活动信息。
- 负责更新
pg_stat_*,pg_statio_*等系统视图的数据。 - 将收集到的数据定期写入磁盘(
pg_stat_tmp目录下的文件),以便在服务器重启后能保留部分信息。
- 进程出问题的影响:
- 如果 Stats Collector 挂掉,不会导致实例崩溃。
- 但会导致所有统计信息视图 (
pg_stat_*,pg_statio_*) 的数据停止更新或变得不准确。 - 影响:无法通过标准视图监控数据库活动、性能、表/索引使用情况;
pg_stat_statements扩展(如果安装)也无法记录新查询;自动清理决策可能因缺少最新统计信息而受影响。
- 排查命令:
ps aux | grep postgres | grep stats: 确认进程存在。- 观察
pg_stat_activity,pg_stat_database等视图的数据是否还在变化(例如,xact_commit计数器是否增长)。如果长时间不变,可能 Stats Collector 挂了。 - 检查日志中是否有相关错误。
- 作用功能:
- i. WAL Receiver (WAL 接收进程 - 仅 Standby 服务器)
- 作用功能:
- 在流复制 (Streaming Replication) 的 Standby (从库/副本) 服务器上运行。
- 连接到 Primary (主库) 上的 WAL Sender 进程。
- 接收从 Primary 实时流式传输过来的 WAL 数据。
- 将接收到的 WAL 数据写入 Standby 服务器的
pg_wal目录。 - 如果配置了级联复制,它也可以作为发送方。
- 进程出问题的影响:
- 如果 WAL Receiver 挂掉,不会导致 Standby 服务器崩溃。
- 但会导致复制中断。Standby 服务器将无法接收和应用新的 WAL 数据,复制延迟 (
replay_lag) 会持续增长。 - 影响:Standby 的数据变得过时,无法用于读负载均衡或快速故障切换。
- 排查命令 (在 Standby 上执行):
ps aux | grep postgres | grep receiver: 确认进程存在。SELECT * FROM pg_stat_wal_receiver;: 关键视图!status: 状态 (streaming正常)。receive_start_lsn/received_lsn: 接收到的 WAL 位置。last_msg_send_time/last_msg_receipt_time: 最后消息收发时间,判断是否卡住。slot_name: 使用的复制槽(如果有)。conninfo: 连接主库的信息(部分掩码)。
tail -f <Standby 日志文件>: 查找连接错误、认证失败、网络超时等。- 在主库上:
SELECT * FROM pg_stat_replication WHERE application_name = '<你的 Standby 标识>';查看主库视角的发送状态(state,sent_lsn,write_lsn,flush_lsn,replay_lsn,sync_state)。
- 作用功能:
- j. WAL Sender (WAL 发送进程 - 仅 Primary 服务器)
- 作用功能:
- 在 Primary 服务器上运行,用于支持流复制或备份工具(如
pg_basebackup)。 - 响应 Standby 服务器 WAL Receiver 的连接请求。
- 读取 Primary 的 WAL 数据,并将其流式传输给连接的 Standby 或备份客户端。
- 每个连接到 Primary 的 Standby 或备份客户端都会对应一个独立的 WAL Sender 进程。
- 在 Primary 服务器上运行,用于支持流复制或备份工具(如
- 进程出问题的影响:
- 单个 WAL Sender 崩溃通常不会导致 Primary 实例崩溃。
- 但会导致连接到该 Sender 的特定 Standby 或备份客户端断开连接,复制或备份中断。
- 如果大量 Sender 崩溃或所有 Sender 都因网络等原因失败,可能表明 Primary 存在更严重问题(资源耗尽、网络故障)。
- 排查命令 (在 Primary 上执行):
ps aux | grep postgres | grep sender: 查看所有 WAL Sender 进程。SELECT * FROM pg_stat_replication;: 关键视图! 查看每个 Sender 的状态:pid: Sender 的进程 ID。usename,application_name: 连接的用户和应用名(通常是 Standby 标识)。client_addr,client_hostname: Standby 的地址。state: 状态 (streaming正常)。sent_lsn,write_lsn,flush_lsn,replay_lsn: 复制的进度位置。sync_state: 同步模式 (async,sync,potential等)。write_lag,flush_lag,replay_lag: 复制延迟。
tail -f <Primary 日志文件>: 查找与特定 Sender 或 Standby 连接相关的错误(如认证失败、连接断开、WAL 读取错误)。
- 作用功能:
- a. Logger (Syslogger - 可选但强烈推荐启用)
-
客户端后端进程 (Client Backend Processes / Postgres)
- 作用功能:
- 这是处理实际客户端连接和查询的进程。
- 当客户端(如 psql, JDBC 应用)连接到数据库时,Postmaster 会为这个连接 fork 一个新的 Postgres 子进程 (在
ps输出中通常就叫postgres)。 - 该进程负责:
- 与客户端通信(接收 SQL 命令,返回结果)。
- 解析、优化、执行 SQL 查询。
- 访问共享缓冲区或从磁盘读取数据。
- 生成 WAL 记录。
- 管理该连接的事务状态。
- 进程出问题的影响:
- 单个后端进程崩溃通常不会导致整个实例崩溃(感谢进程隔离)。Postmaster 会检测到子进程退出,记录错误日志,并释放该进程占用的资源(锁、内存等)。
- 影响范围通常是该进程所服务的特定客户端连接:该连接会断开,正在执行的事务会回滚。客户端会收到连接错误。
- 如果崩溃是由底层严重问题(如共享内存损坏)引起的,有可能引发级联反应导致其他进程或整个实例不稳定甚至崩溃(这种情况较少见但更危险)。
- 长时间运行或持有锁的后端进程如果挂起(非崩溃,而是卡死),会阻塞其他操作,需要手动干预。
- 排查命令:
ps aux | grep postgres | grep -v grep: 查看所有进程列表。客户端后端进程的命令行通常包含连接信息(如postgres: user dbname host [local])。SELECT * FROM pg_stat_activity;: 最重要视图! 查看所有活动连接/进程:pid: 进程 ID。usename,datname: 用户名和数据库名。application_name: 客户端应用名。client_addr,client_hostname: 客户端地址。backend_start,xact_start,query_start: 进程、事务、查询开始时间。state: 状态 (active,idle,idle in transaction,fastpath function call,disabled- 如果被跟踪)。query: 当前正在执行或最后执行的查询。对于idle状态,这是上一个查询。wait_event_type,wait_event: 如果进程在等待(锁、IO、Latch 等),这里会显示等待类型和事件。
- 定位问题进程:
- 卡死的查询:查找
state='active'且query_start很早,或wait_event不为空的进程。 - 长时间空闲事务 (
state='idle in transaction'): 可能持有锁阻塞他人。 - 检查日志:后端进程的崩溃通常会在日志中生成详细的错误报告(包括引起崩溃的 SQL 语句片段、错误代码如
XX000内部错误、堆栈跟踪)。日志行通常包含该后端的 PID。
- 卡死的查询:查找
- 干预命令 (谨慎使用!):
SELECT pg_cancel_backend(pid);: 尝试优雅地取消后端进程当前正在执行的查询(类似按 Ctrl+C)。事务可能回滚。SELECT pg_terminate_backend(pid);: 强制终止整个后端进程(类似 kill -9)。连接会断开,事务会回滚。可能导致客户端应用报错。仅在pg_cancel_backend无效时使用。
- 作用功能:
总结与关键排查思路
- 区分进程类型: 遇到问题先判断是主进程、后台进程、还是客户端进程的问题。
ps和pg_stat_activity是第一步。 - 日志是生命线:
tail -f实时监控数据库日志文件 (log_directory/log_filename) 是诊断任何进程问题(尤其是崩溃、启动失败、严重错误)的最核心手段。错误信息通常非常明确。 - 利用统计视图:
pg_stat_activity: 查看所有活动进程/连接状态。pg_stat_bgwriter: 检查点、后台写状态。pg_stat_wal/pg_stat_wal_writer: WAL 写入状态 (较新版本)。pg_stat_archiver: 归档状态 (关键!)。pg_stat_replication: 主库复制发送状态 (关键!)。pg_stat_wal_receiver: 备库复制接收状态 (关键!)。pg_stat_all_tables/pg_stat_user_tables: 表级统计,特别是死元组 (n_dead_tup) 和上次自动清理时间 (last_autovacuum,last_autoanalyze)。pg_stat_progress_vacuum: 查看 VACUUM 进度。
- 系统监控工具:
top/htop,vmstat,iostat,iotop等监控服务器整体资源(CPU, 内存, 磁盘 I/O, 网络)使用情况,判断是否是资源瓶颈导致进程问题。 - 配置检查: 使用
SHOW <parameter>;或查询pg_settings视图检查关键配置参数是否合理(如内存设置shared_buffers,work_mem;WAL 设置;检查点设置;自动清理设置;复制设置;归档命令等)。 - 谨慎干预: 对后端进程使用
pg_cancel_backend和pg_terminate_backend要非常小心,确保了解后果,优先尝试从应用端终止操作或等待超时。
理解每个进程的角色和相互协作关系,熟练运用日志和统计视图,结合系统监控工具,是高效管理和排查 PostgreSQL 问题的关键。
欢迎关注我的公众号《IT小Chen》
5万+

被折叠的 条评论
为什么被折叠?



