文章目录
-
- [一、Postmaster 概述](#一、Postmaster 概述)
-
- [1.1 什么是 Postmaster?](#1.1 什么是 Postmaster?)
- [1.2 Postmaster 的核心职责](#1.2 Postmaster 的核心职责)
- [1.3 PostgreSQL 的主要进程类型](#1.3 PostgreSQL 的主要进程类型)
- [1.4 协作流程示例](#1.4 协作流程示例)
- 二、调试与监控建议
-
- [2.1 查看进程树](#2.1 查看进程树)
- [2.2 日志分析](#2.2 日志分析)
- [2.3 使用 pg_stat_activity](#2.3 使用 pg_stat_activity)
- [三、Postmaster 的启动流程](#三、Postmaster 的启动流程)
-
- [3.1 初始化环境](#3.1 初始化环境)
- [3.2 创建共享内存与信号量](#3.2 创建共享内存与信号量)
- [3.3 启动辅助进程](#3.3 启动辅助进程)
- [3.4 监听客户端连接](#3.4 监听客户端连接)
- 四、子进程的创建与管理
-
- [4.1 客户端连接处理](#4.1 客户端连接处理)
- [4.2 子进程状态跟踪](#4.2 子进程状态跟踪)
- [4.3 子进程异常退出处理](#4.3 子进程异常退出处理)
- 五、进程间通信(IPC)机制
-
- [5.1 共享内存(Shared Memory)](#5.1 共享内存(Shared Memory))
- [5.2 信号(Signals)](#5.2 信号(Signals))
- [5.3 消息队列(仅限部分场景)](#5.3 消息队列(仅限部分场景))
- [5.4 文件系统协调](#5.4 文件系统协调)
- 六、容错与恢复机制
-
- [6.1 崩溃恢复(Crash Recovery)](#6.1 崩溃恢复(Crash Recovery))
- [6.2 子进程重启策略](#6.2 子进程重启策略)
- [6.3 "Smart Shutdown" vs "Fast Shutdown"](#6.3 “Smart Shutdown” vs “Fast Shutdown”)
- 七、性能与扩展性考量
-
- [7.1 进程模型的优缺点](#7.1 进程模型的优缺点)
- [7.2 最大连接数限制](#7.2 最大连接数限制)
PostgreSQL 是一个功能强大、开源的关系型数据库管理系统(RDBMS),其架构设计以稳定性、可扩展性和并发处理能力著称。在 PostgreSQL 的众多核心组件中,Postmaster 进程扮演着"总指挥"的角色,负责启动、监控和协调所有其他子进程(如后端服务进程、WAL 写入器、检查点进程、自动清理进程等)。理解 Postmaster 与子进程之间的协作机制,是深入掌握 PostgreSQL 内部工作原理的关键。
本文将从源码视角出发,系统性地剖析 Postmaster 的职责、生命周期、子进程管理模型、通信机制、容错策略以及典型协作流程,帮助读者构建对 PostgreSQL 进程模型的整体认知。
一、Postmaster 概述
1.1 什么是 Postmaster?
Postmaster 是 PostgreSQL 实例的主守护进程(main daemon process),通常由 postgres 可执行文件在特定模式下启动(即不带 -C、-D 等参数时的默认行为)。它在数据库集群启动时作为第一个用户态进程运行,PID 通常记录在 $PGDATA/postmaster.pid 文件中。
Postmaster 是 PostgreSQL 架构的"中枢神经系统",其设计体现了 Unix 哲学中的"单一职责"与"进程隔离"思想。通过精心设计的子进程协作机制,PostgreSQL 实现了高可靠性、强一致性和良好的并发处理能力。
注意 :虽然命令名为
postgres,但在启动为守护进程时,其内部逻辑会进入PostmasterMain()函数,此时该进程被称为 Postmaster。
1.2 Postmaster 的核心职责
- 监听客户端连接请求(通过 Unix 域套接字或 TCP/IP)
- 派生(fork)新的后端进程(Backend Process) 来处理每个客户端连接
- 启动并管理后台辅助进程(如 WAL writer、Checkpointer、Autovacuum launcher、Stats collector 等)
- 监控所有子进程的健康状态
- 处理信号(如 SIGTERM、SIGINT、SIGHUP)以实现优雅关闭、重载配置等
- 协调崩溃恢复与正常启动流程
- 维护共享内存(Shared Memory)和信号量(Semaphores)
1.3 PostgreSQL 的主要进程类型
PostgreSQL 采用 多进程模型(Multi-process Model),而非多线程模型。这是其区别于 MySQL(默认多线程)的重要特征之一。每个客户端连接由一个独立的后端进程服务,这种设计简化了内存管理和并发控制,但也带来更高的资源开销。
| 进程类型 | 功能说明 |
|---|---|
| Postmaster | 主控进程,负责整体协调 |
| Backend (Postgres) | 处理单个客户端连接的后端进程 |
| WAL Writer | 异步将 WAL 缓冲区写入磁盘 |
| Checkpointer | 执行检查点,将脏页刷盘 |
| Background Writer | 后台写入器,提前刷脏页以减少 Checkpoint 压力 |
| Autovacuum Launcher/Worker | 自动清理死元组、更新统计信息 |
| Stats Collector | 收集数据库运行统计信息 |
| Logger | (可选)集中日志写入进程 |
| Archiver | 归档 WAL 日志文件(若启用归档) |
所有子进程均由 Postmaster 通过
fork()创建,并继承其打开的文件描述符和共享内存段。
1.4 协作流程示例
场景:执行一个 UPDATE 语句
- 客户端连接 → Postmaster fork Backend
- Backend 进程:
- 获取共享缓冲区中的页面
- 修改元组,生成 WAL 记录写入 WAL buffer
- 更新 CLOG 标记事务状态
- WAL Writer 后台进程定期将 WAL buffer 刷盘
- Background Writer 提前将脏页写入 OS 缓存
- Checkpointer 在检查点时强制刷所有脏页并更新
pg_control - 若事务提交,Backend 发送
XLOG_COMMIT记录 - 所有操作通过共享内存和锁机制保持一致性
整个过程中,Postmaster 不直接参与 SQL 执行,但确保所有子进程正常运行、资源可用。
二、调试与监控建议
2.1 查看进程树
bash
ps -ef | grep postgres
典型输出:
postgres 12345 1 0 10:00 ? 00:00:00 /usr/lib/postgresql/14/bin/postgres -D /var/lib/postgresql/14/main
postgres 12346 12345 0 10:00 ? 00:00:00 postgres: checkpointer
postgres 12347 12345 0 10:00 ? 00:00:00 postgres: writer
postgres 12348 12345 0 10:00 ? 00:00:00 postgres: walwriter
postgres 12349 12345 0 10:00 ? 00:00:00 postgres: autovacuum launcher
postgres 12350 12345 0 10:00 ? 00:00:00 postgres: stats collector
postgres 12351 12345 0 10:01 ? 00:00:00 postgres: user db 192.168.1.100(54321) idle
2.2 日志分析
启用 log_connections, log_disconnections, log_checkpoints 等参数,观察 Postmaster 行为。
2.3 使用 pg_stat_activity
查看当前活跃 Backend:
sql
SELECT pid, usename, application_name, state, query FROM pg_stat_activity;
三、Postmaster 的启动流程
Postmaster 的启动过程可分为以下几个关键阶段:
3.1 初始化环境
- 解析命令行参数(如
-D datadir) - 验证数据目录有效性
- 读取
postgresql.conf和pg_hba.conf - 初始化日志系统
3.2 创建共享内存与信号量
Postmaster 调用 CreateSharedMemoryAndSemaphores():
- 分配 共享内存段(Shared Memory Segment) ,包含:
- Shared Buffer Pool(缓冲池)
- WAL Buffer
- Lock Manager 数据结构
- ProcArray(活跃进程数组)
- CLOG(事务提交日志)
- 其他全局状态
- 创建 信号量(Semaphores) 用于进程间同步(如 LWLock、SpinLock)
此阶段若失败(如内存不足),Postmaster 将退出并报错。
3.3 启动辅助进程
Postmaster 按顺序 fork 并启动以下后台进程:
c
// src/backend/postmaster/postmaster.c
StartChildProcess(AuxProcType type)
典型启动顺序(部分):
- Logger(若启用)
- Checkpointer
- Writer (BgWriter)
- WAL Writer
- Autovacuum Launcher
- Stats Collector
- Archiver(若启用归档)
每个子进程启动后,会调用对应的 XXXMain() 函数(如 CheckpointerMain()),进入自己的事件循环。
3.4 监听客户端连接
Postmaster 调用 StreamServerPort() 创建监听套接字(Unix + TCP),然后进入主事件循环 ServerLoop(),等待新连接或子进程退出信号。
四、子进程的创建与管理
4.1 客户端连接处理
当客户端尝试连接时:
- Postmaster 的
ServerLoop()检测到新连接(通过select()或poll()) - 调用
ConnCreate()创建连接上下文 - 调用
BackendStartup()→fork()新进程 - 子进程执行
BackendRun(),进入PostgresMain(),开始处理 SQL - 父进程(Postmaster)继续监听
每个 Backend 进程拥有独立的内存空间,但共享共享内存段中的数据结构。
4.2 子进程状态跟踪
Postmaster 维护一个全局数组 BackendList(实际是 PMChildSlot 结构体数组),记录每个子进程的:
- PID
- 状态(正在启动、运行中、已退出等)
- 角色类型(Backend / Checkpointer / WAL Writer 等)
- 启动时间
通过 waitpid(-1, &status, WNOHANG) 非阻塞方式轮询子进程退出状态。
4.3 子进程异常退出处理
若子进程因错误(如段错误、断言失败)崩溃:
- Postmaster 捕获
SIGCHLD信号 - 调用
reaper()信号处理函数 - 通过
waitpid()获取退出状态 - 根据进程类型决定后续动作:
- Backend 崩溃:仅记录日志,不影响其他连接
- 关键后台进程崩溃(如 Checkpointer):可能触发整个实例重启(取决于配置)
- 多次崩溃:Postmaster 可能进入"崩溃循环保护",拒绝新连接或自动重启
PostgreSQL 默认对 Backend 崩溃具有强隔离性------一个连接崩溃不会影响其他连接。
五、进程间通信(IPC)机制
PostgreSQL 子进程与 Postmaster 之间主要通过以下方式通信:
5.1 共享内存(Shared Memory)
- 所有进程映射同一块共享内存
- 包含全局状态(如事务 ID、锁表、缓冲区描述符)
- 使用 LWLock(轻量级锁) 和 SpinLock 保证并发安全
5.2 信号(Signals)
Postmaster 向子进程发送信号以控制其行为:
| 信号 | 用途 |
|---|---|
SIGTERM |
请求优雅关闭 |
SIGQUIT |
请求立即退出(用于崩溃场景) |
SIGHUP |
通知重载配置(部分进程支持) |
SIGUSR1/SIGUSR2 |
自定义用途(如 WAL 切换、检查点触发) |
例如,Checkpointer 通过监听 SIGUSR2 来响应检查点请求。
5.3 消息队列(仅限部分场景)
- Stats Collector 使用 UDP socket 接收其他进程发送的统计消息(避免锁竞争)
- Autovacuum 通过共享内存中的
AutoVacuumShmem结构协调任务分配
5.4 文件系统协调
postmaster.pid:记录主进程 PID、端口、数据目录等global/pg_filenode.map、pg_wal/*.wal等:通过文件系统实现持久化协调
六、容错与恢复机制
6.1 崩溃恢复(Crash Recovery)
若数据库非正常关闭(如断电),Postmaster 在下次启动时会:
- 检测到
pg_wal中存在未应用的 WAL 记录 - 启动 Startup Process(特殊 Backend)
- 执行 Redo(重做) 操作,回放 WAL 日志
- 完成恢复后,才允许普通 Backend 连接
Startup Process 也是由 Postmaster fork 出的子进程,但它不接受客户端连接。
6.2 子进程重启策略
- 非关键进程(如 Autovacuum Worker):崩溃后可由 Launcher 重新派生
- 关键进程(如 WAL Writer):若崩溃,Postmaster 可能尝试重启;若频繁失败,可能进入安全模式
- Backend:崩溃即终止,由客户端重连处理
6.3 "Smart Shutdown" vs "Fast Shutdown"
Postmaster 支持多种关闭模式:
| 模式 | 行为 |
|---|---|
| Smart(默认) | 等待所有客户端断开后关闭 |
| Fast | 立即终止所有 Backend,执行检查点后关闭 |
| Immediate | 不做清理,直接退出(下次启动需恢复) |
通过 pg_ctl stop -m [smart|fast|immediate] 控制。
七、性能与扩展性考量
7.1 进程模型的优缺点
优点:
- 进程隔离性强,单点故障影响小
- 调试简单(每个进程独立 core dump)
- 兼容 Unix 传统工具(如
ps,kill)
缺点:
- 进程创建开销大(相比线程)
- 内存占用高(每个 Backend 有独立私有内存)
- 上下文切换成本高(高并发时)
PostgreSQL 14+ 引入 Connection Pooling(如 pgbouncer)缓解连接开销。
7.2 最大连接数限制
由 max_connections 参数控制(默认 100)。每个连接消耗约几 MB 内存,因此受系统资源限制。
可通过 superuser_reserved_connections 保留连接给管理员。