在基于 Repmgr 管理的 PostgreSQL 流复制集群中,standby promote 和 standby follow 是运维人员最常接触却又最容易混淆的两个命令。前者将 standby 节点提升为可读写的主库,后者则让一个曾经的独立主库重新以 standby 身份跟随当前主库。理解这两个命令的内部机制以及它们在整个故障切换生命周期中的位置,是保障集群高可用性的关键。

一、Standby Promote 的本质与触发条件
repmgr standby promote 命令本质上是对 PostgreSQL 原生 pg_ctl promote 操作的封装,但它同时会更新 Repmgr 元数据并通知集群状态变更。当一个 standby 节点执行 promote 后,PostgreSQL 会结束恢复模式,清空 recovery.signal 标记(或在旧版本中删除 recovery.conf),并将该节点标记为正常的主数据库实例。这一动作意味着该节点从此开始生成自己的新时间线,如果原主库仍然在线,就会立即形成时间线分叉,导致脑裂。
Repmgr 在 promote 过程中会执行一系列检查:确认当前节点确实是 standby 角色、尝试断开与原主库的复制连接、并调用 pg_ctl promote。提升完成后,Repmgr 会将本地节点的类型由 standby 改为 primary,并尝试广播给所有剩余的 standby 节点(如果配置了 witness 或其它机制),以便它们可以自动 follow 到新主库。需要注意的是,只有在 Repmgr 的自动故障转移(autofailover)触发时,才会在 promote 之前执行 stonith 等隔离操作;手动执行 standby promote 时,Repmgr 不会主动杀死原主库进程,因此必须由 DBA 确保原主库已被彻底关闭或隔离。
在命令行中,最常用的手动提升方式为:
$ repmgr -f /etc/repmgr.conf standby promote
该命令的输出会显示检查步骤,例如是否成功停止复制、是否已提升等。如果提升失败,通常是因为节点当前不是 standby(比如已经被提升过),或者原主库仍然可见且复制连接还存在。这种情形下,可通过添加 --siblings-allow 或 --force 参数强制提升,但前提是已经人工确认原主库不会继续写入数据。
二、Follow 命令:将独立节点重新纳入复制链
repmgr standby follow 的作用是让一个目前并非 standby 的节点(通常是修复后的原主库)开始追随当前的主库。它的底层逻辑是修改该节点的复制配置,使其连接到新主库,并启动恢复进程。如果节点原本是一个独立的主库(例如故障恢复后没有自动成为备库),直接执行 follow 可能会因为时间线不一致而失败,此时需要借助 pg_rewind 来快速对齐数据。
Follow 命令执行时,会先检查目标新主库是否可达、复制槽和连接权限是否正常,然后生成或修改 postgresql.auto.conf 中的 primary_conninfo 参数,并写入 recovery.signal 文件(或旧版的 standby.signal)。重新启动 PostgreSQL 后,该节点就会以 standby 模式连接到新主库,开始接收并应用 WAL 日志。如果 Repmgr 检测到当前节点数据目录比新主库更旧(即时间线落后),它会提示需要先执行 repmgr node rejoin 或手动运行 pg_rewind;反之,若数据目录处于同一时间线且有部分未应用的 WAL,则可直接 follow。
典型的使用场景是:当旧主库因网络抖动被隔离后又恢复,但此时集群已经将某个 standby 提升为了新主库。DBA 可以在旧主库上运行:
$ repmgr -f /etc/repmgr.conf standby follow --upstream-node-id=3
--upstream-node-id 指定新主库在 Repmgr 元数据中的节点 ID。执行后 Repmgr 会自动执行必要的步骤,包括停止旧实例、进行 pg_rewind(如果配置了自动 rewind)、修改配置并启动。如果旧主库的数据目录已经严重损坏,则可能需要先 repmgr standby clone 从新主库全量重构数据,再 follow。
三、Promote 与 Follow 在故障切换中的协同流程
一次完整的计划外故障切换通常遵循以下步骤:检测主库故障 → 隔离主库(避免脑裂)→ 在候选 standby 上执行 promote → 将应用连接重定向到新主库 → 修复旧主库硬件/网络后,将其作为新 standby 加入集群。其中 promote 和 follow 分别是切换和回切的关键动作。
在 Repmgr 自动故障转移中,守护进程 repmgrd 会根据监控信息触发 promote,随后通过 event notification 通知其余 standby 自动 follow。但在手动操作时,DBA 必须自己协调顺序。例如,假设原主库 node1 宕机,node2 是备用库,操作流程为:
# 在 node2 上提升 $ repmgr standby promote # 在修复后的 node1 上 $ repmgr standby follow --upstream-node-id=2
为了防止数据丢失,强烈建议在 promote 之前确认 synchronous_standby_names 配置以及 repmgr cluster show 中的同步状态。如果原主库采用异步复制,直接 promote 可能导致部分已提交事务丢失;这种情况下,可以尝试在原主库还部分可用时,通过 pg_receivewal 等工具抢救 WAL,再在 promote 后手动应用。
当旧主库通过 follow 重新成为 standby 后,还需要验证其是否正常追数据。通过 repmgr cluster show 可以看到节点状态变为 standby 且 lag 逐渐减小。如果不幸出现时间线分歧导致 follow 失败,则可以执行:
$ repmgr node rejoin -d 'host=new_primary_ip' --force-rewind
这会调用 pg_rewind 将旧主库的数据回退到与新主库一致的分叉点,然后通过 follow 恢复复制关系。
四、常见误区与故障排查思路
误区之一是把 standby follow 当作一个可以随时执行的万能恢复命令。当一个节点已经是 standby 且正在跟随某个主库时,对它再次执行 follow 可能会因为复制连接冲突而报错。此时应检查该节点当前的复制状态:pg_stat_wal_receiver 视图会显示活跃的 WAL 接收进程。如果已有接收进程,则表示已经在跟随。
另一个常见的混淆点是将 standby promote 与 PostgreSQL 的 pg_ctl promote 完全等同。尽管最终效果都是提升备库,但 Repmgr 的 promote 还承担着元数据同步、事件通知等职责。如果直接使用 pg_ctl promote,Repmgr 集群视图中的节点角色将不会自动更新,可能导致后续监控和自动切换逻辑混乱。补救办法是手动更新 repmgr.nodes 表或重新初始化节点元数据。
在排查 follow 失败时,可以从以下几个方向入手:
1. 网络连通性:在新主库上 telnet <new_primary_ip> 5432 测试,确保防火墙允许连接;
2. 复制槽冲突:如果旧主库曾持有与新主库冲突的复制槽,需要用 SELECT pg_drop_replication_slot('slot_name') 清除;
3. 时间线分歧:查看 PostgreSQL 日志,若出现 requested timeline X is not a child of this server's history,则需要运行 pg_rewind;
4. 认证失败:检查新主库的 pg_hba.conf 中是否允许来自旧主库 IP 的 replication 连接,并确认 repmgr.conf 中的 conninfo 中包含正确的用户和密码。
通过理解 promote 与 follow 两种操作的动作边界和触发条件,DBA 便能在复杂的故障恢复中做出准确的决策,大幅缩短停机时间,并有效规避数据不一致的风险。
repmgrstandby_promotefollow修改时间:2026-08-12 08:31:01