pgrac 在 PostgreSQL 的进程模型之上叠加了一套完整的集群常驻进程体系。postmaster fork 机制保持不变,BackendType enum 在原有基础上追加 14 个新值;稳态下一个 4 节点主节点集群每节点运行约 24 个进程——10 个 PG 原生进程(其中若干做了针对性调整)加上 14 个 pgrac 新增 cluster daemon。
理解进程树是排查集群问题的第一步:pg_stat_activity 的 backend_type 字段直接映射到 BackendType enum,ps aux 输出中的 postgres: lms 0、postgres: lmd 等名称与设计文档一一对应。本章建立进程树的全景认知——每个进程是什么、为什么独立存在、以什么顺序启动和关闭、通过什么机制通信。进程内部的协议细节(GES 消息编码、PCM 状态机转换、RDMA QP 管理)留给深度页;本章只建立结构性词汇表。
postmaster 是整棵进程树的根。它在共享内存和锁结构初始化完成后,按照 4 个 Phase 依次 fork 所有子进程;子进程之间通过共享内存、信号和节点间 Interconnect 通信,不存在父子进程的直接依赖链(postmaster 是监控者,不是中间路由)。
postmaster
│
┌───────────────┴───────────────┐
│ │
PG natives pgrac new
─────────── ──────────────
walwriter (+BOC) LMS × N (default 4)
bgwriter LMD
autovacuum LCK0
checkpointer LMHB
archiver DIAG
logical_repl RECO
... GRD0
...
图中"PG natives"一侧有若干进程做了 pgrac 专项调整(见 §8.2),并非完全保持原始行为。"pgrac new"一侧均为全新进程,在 PG 原生 BackendType enum 之外追加,不破坏任何既有 ABI。
稳态进程数估算:4 个 LMS worker + 1 LMD + 1 LCK + 1 LMON + 1 Interconnect Listener + 1 Heartbeat + 1 Undo Cleaner + 1 TT GC + 1 DIAG + 1 Cluster Stats + 1 Sinval Broadcaster = 14 个 pgrac 必启动进程;加上约 10 个 PG 原生进程,合计约 24 进程 / 节点(primary 稳态)。
Recovery Coordinator、Recovery Worker(动态数量)和 MRP 不计入稳态:Recovery Coordinator / Worker 仅在 reconfig 期间按需 fork,完成后退出;MRP 仅在 standby + ADG 模式下启动。
PG 原生进程全部保留,部分做了针对性扩展。扩展原则:能在原有进程内追加逻辑的,不新增进程(BOC 嵌入 walwriter 就是典型);扩展只在集群模式生效,单机部署路径不变。
| PG 原生进程 | 调整内容 | 备注 |
|---|---|---|
postmaster | 启动时初始化 GES client;注册到 GRD;监控所有 pgrac 进程;进程死亡时做 restart / instance crash 决策 | 核心监控者 |
walwriter | 内嵌 BOC:100 μs 周期 flush;SCN piggyback 维护;per-thread WAL stream 处理 | 最重要的调整,见下注 |
bgwriter | 写脏块前 PCM 状态 check:仅 X 模式可 flush,非 X 模式跳过(让 PCM master 协调) | 防止跨节点 buffer 冲突 |
checkpointer | 跨节点 barrier checkpoint;触发 cluster checkpoint barrier | 关联 #18 |
archiver | per-thread WAL 归档;thread_id 隔离归档路径;归档完成上报 GRD | 关联 AD-009 |
autovacuum launcher | xid wraparound 计算感知 per-instance xid 分段(AD-012 例外 10) | 逻辑不变,边界感知 |
startup | 仅一次性 recovery:crash recovery 入口;检测 merged recovery 需求;触发 Recovery Coordinator;完成后退出。不再承担 standby 持续 apply | 持续 apply 交给 MRP |
walsender | 保留,无调整 | — |
walreceiver | ADG 下 per-thread 接收 | — |
logger | 保留,无调整 | — |
logical rep launcher / worker | 保留,无调整 | — |
walwriter 内嵌 BOC 是 §3.2 SCN 一章中描述的 "BOC flush" 的实现宿主。BOC 触发频率高(每 100 μs 一次)但单次工作量小,独立进程开销超过收益;BOC 与 WAL 落盘时序强耦合(commit 后 BOC 推进 SCN),内嵌保持了时序一致性。Oracle 的 BOC 也是 LGWR 内嵌职责,设计上保持对齐。
startup process 的重要调整:PG 原生 startup 在 standby 模式下会持续 apply WAL 直到 promote——这一行为在 pgrac 中移交给 MRP。pgrac 的 startup 只做启动期 crash recovery,完成后退出,职责单一、便于故障隔离。
pgrac 新增 14 类后台进程,按子系统分为 5 组。以下表格给出每个进程的名称、稳态数量和一句话职责;详细设计见 §8.5 IPC 模型和各功能深度页。
| # | 子系统 | 进程 | 稳态数量 | 一句话职责 |
|---|---|---|---|---|
| 1 | 锁与缓存 | LMS (Lock Master Service) | N=4(默认,GUC cluster.lms_workers 可调 1~16) | 处理跨节点 PCM/GES 远程请求,响应 buffer ship,执行锁授予 / 撤销决策,并附带 SCN piggyback。 |
| 2 | 锁与缓存 | LMD (Lock Manager Daemon) | 1 | 接收本节点 enqueue 请求,维护 wait queue(FIFO + 3 级优先级),构造 wait-for graph 片段供死锁检测。 |
| 3 | 锁与缓存 | LCK (Lock Process) | 1 | 持有 instance-level 锁(dictionary lock、cluster catalog lock),避免 LMS worker 被 instance 锁长期阻塞。 |
| 4 | 锁与缓存 | LMON (Lock Monitor) | 1 | 监控集群节点状态,协调 Reconfiguration,触发 GRD 重建和 fence 决策,启动 Recovery Coordinator。 |
| 5 | 集群通信 | Interconnect Listener | 1 | 监听 RDMA QP / TCP fallback 端口,接收消息并分发到 LMS / LMD / LCK 等 worker queue。 |
| 6 | 集群通信 | Heartbeat | 1 | 每秒向所有节点发送心跳,维护节点存活状态,3 秒未收到标记 SUSPECT、6 秒标记 DEAD 后通知 LMON。 |
| 7 | Undo / TT | Undo Cleaner | 1 | 每 30 秒扫描本实例 undo segments,回收 RECYCLABLE 空间,维护 retention 窗口,推进 WRAP counter。 |
| 8 | Undo / TT | TT GC (Transaction Table GC) | 1 | 每 10 秒扫描 TT slot,回收 commit_scn 已被全集群 oldest_active_scn 超过的 expired slot 供新事务复用。 |
| 9 | 可观测 | DIAG | 1 | 跨节点诊断快照:检测 long-wait(默认 60 秒)触发 hang dump,接收其他节点的诊断请求,聚合 cluster log。 |
| 10 | 可观测 | Cluster Stats | 1 | 每 10 秒采样集群指标,填充 pg_stat_cluster_* 视图,跨节点聚合 wait events 历史(默认保留 7 天)。 |
| 11 | 可观测 | Sinval Broadcaster | 1 | 批量广播本节点 catcache / relcache invalidation 消息到所有其他节点,并注入对端 sinval queue,保持 catalog 一致性。 |
| 12 | 集中恢复 | Recovery Coordinator | 1(仅 reconfig) | 收集死亡节点 WAL,协调 k-way SCN merge,分配 Recovery Worker,协调 PCM lock 状态恢复,完成后退出。 |
| 13 | 集中恢复 | Recovery Worker | M 动态(仅 reconfig) | 接收 Coordinator 分配的 WAL 段,执行 redo / undo apply,上报进度,完成后退出。 |
| 14 | 集中恢复 | MRP (Managed Recovery Process) | 1(仅 standby + ADG) | 持续接收 walreceiver 的 per-thread WAL stream,集中 apply(对齐 Oracle MRP 模型),推进 apply_scn,直到 promote 退出。 |
Sinval Broadcaster 是关键安全进程:crash 后 postmaster 立即 restart,超过 3 次 → instance crash。catcache / relcache 不一致是数据正确性问题,不是性能问题,不可降级。
BackendType enum 扩展:14 个新进程对应 miscadmin.h 追加的 14 个 enum 值(B_CLUSTER_STATS / B_DIAG / B_HEARTBEAT / B_INTERCONNECT / B_LCK / B_LMD / B_LMON / B_LMS_WORKER / B_MRP / B_RECOVERY_COORD / B_RECOVERY_WORKER / B_SINVAL_BCAST / B_TT_GC / B_UNDO_CLEANER),追加到现有枚举末尾,不改变既有值,保持 PG 16.13 ABI 兼容。pg_stat_activity 的 backend_type 字段自动展示,视图层无需修改。
启动顺序体现了集群化依赖链:必须先有网络和心跳,才能启动锁服务;必须先有锁服务,才能进行 recovery;必须 recovery 完成,才能开始正常服务。
postmaster
│
├── Phase 0:基础
│ └─ logger(日志先行)
│
├── Phase 1:集群基础 ← 60 秒超时,失败 → instance crash
│ ├─ Interconnect Listener (网络层就绪)
│ ├─ Heartbeat (心跳建立)
│ └─ LMON (加入集群 / GRD 同步)
│
├── Phase 2:锁服务 ← 30 秒超时,失败 → instance crash
│ ├─ LMS0..LMSn (并行 fork)
│ ├─ LMD
│ └─ LCK
│
├── Phase 3:恢复(按需) ← 600 秒超时(GUC cluster.recovery_timeout)
│ ├─ startup process (crash recovery 入口)
│ │ ├─ 检测 merged recovery → LMON 启动 Recovery Coordinator
│ │ ├─ Recovery Coordinator → spawn Recovery Workers
│ │ └─ 完成后 startup / Coordinator / Workers 全部退出
│ └─ [standby + ADG only] MRP 启动
│
└── Phase 4:正常服务 ← 30 秒超时,单进程失败 restart 3 次
├─ checkpointer / bgwriter / walwriter (内嵌 BOC)
├─ archiver / autovacuum launcher
├─ TT GC / Undo Cleaner / Sinval Broadcaster
├─ DIAG / Cluster Stats / logical rep launcher
└─ 开始接受 client 连接
三条关键依赖 arrow:
关闭逆序:关闭顺序与启动逆向,关键不变量是"必须先释放全局锁(Phase 2 进程关),再断网(Phase 1 进程关)"——若顺序颠倒,其他节点无法感知锁释放,导致集群状态不一致。
关闭顺序:
1. 拒绝新连接
2. 等待 client backend 退出(默认 30s)
3. Phase 4 进程(Cluster Stats / DIAG / Sinval Broadcaster / Undo Cleaner / TT GC / archiver / autovacuum)
4. walwriter / bgwriter / checkpointer(final checkpoint)
5. [standby] MRP
6. Phase 2 进程(LCK / LMD / LMS0..LMSn)← 释放全局锁
7. Phase 1 进程(LMON / Heartbeat / Interconnect Listener)← 通知 graceful leave
8. logger
9. postmaster 退出
pgrac 进程间通信分为两层:同节点进程依赖共享内存 + 信号 + 进程内 queue;跨节点进程依赖 Interconnect Listener 分发的消息队列。两层边界清晰,不存在"跨节点直接访问共享内存"的设计——跨节点数据访问全部经过协议消息(PCM block ship / GES lock grant)。
同节点 IPC:
| 方式 | 用途 |
|---|---|
| 共享内存(SysV / mmap) | 锁结构、buffer pool、TT slot、GRD cache |
| 信号(SIGTERM / SIGUSR1 / SIGUSR2) | postmaster → 子进程控制(与 PG 原生完全一致) |
Latch(SetLatch) | 唤醒等待的 backend / worker(复用 PG 机制) |
| 进程内 queue(lock-free ring buffer) | LMS dispatcher → LMS worker(见 §8.5.1) |
跨节点 IPC:
| 方式 | 用途 |
|---|---|
| Interconnect(RDMA / TCP) | 所有跨节点协议消息(PCM / GES / SCN / 心跳) |
| Listener → worker queue | Interconnect Listener 接收入站消息后按 resource hash 分发 |
| Worker → Listener queue | 各 worker 将出站消息投递给 Listener 统一发送 |
LMS 是进程树中并发度最高的组件:N 个 worker(默认 4)共享一个 Interconnect Listener 入口,但每个 worker 处理独立的资源子集,不存在 worker 间的锁竞争。
分片策略:worker_id = hash(resource_id) % N。resource_id 对于 PCM 是 block 的 (tablespace_oid, relfilenode, block_no) 三元组,对于 GES 是锁资源名。同一资源始终由同一 worker 处理,避免并发 race。
消息流转:
跨节点消息到达
│
Interconnect Listener(单一入站点)
│
├─ 读取 msg.resource_id
├─ 计算 worker_id = hash(resource_id) % N
└─ 投递到 workers[worker_id].queue(lock-free ring buffer)
LMS worker 内部循环:
while (running):
msg = my_queue.recv() # 阻塞等待
handle_pcm_or_ges_msg(msg) # PCM 状态机 / GES grant
update_local_scn(msg.piggyback_scn) # Lamport 推进
if (reply needed):
outbound_queue.send(reply) # 交给 Listener 发出
这一设计的关键属性:Listener 是单线程扇出,worker 是单线程串行处理各自的队列——系统中不存在多个 writer 竞争同一 GRD 条目的场景(同一资源的所有消息串行到同一个 worker),RDMA write 操作也因此无需额外的 per-resource 锁。
N 的选择:默认 N=4 对应 4 节点 OLTP 集群 100K TPS 场景约 1.0–2.0 核 CPU 占用。N 过小时 worker queue 积压(监控 pg_stat_cluster_workers.queue_depth),N 过大时 LRU cache 分片效果下降(每个 worker 缓存的 GRD 条目减少)。生产调优建议参考 pg_stat_cluster_workers 视图的 queue_depth 字段。
故障决策原则:LMS / LMD / LCK / LMON / Heartbeat / Interconnect Listener / Sinval Broadcaster 是"关键进程"——crash 后 postmaster restart,超过 3 次 → instance crash(被其他节点 fence)。Undo Cleaner / TT GC / DIAG / Cluster Stats 是"降级可恢复进程"——crash 后 restart,超过 3 次 → 仅警告,不 crash(GC 滞后或监控降级,但集群正确性不受影响)。
深度协议细节请参阅以下资源:
pg_stat_cluster_workers 视图字段、进程级故障决策表、GUC 参数完整列表(cluster.lms_workers / cluster.recovery_timeout / cluster.heartbeat_interval 等)background-process-design.md — 14 类新增进程 + 7 类 PG 原生调整的完整规格:内存占用估算(稳态