在PostgreSQL高可用体系中,Patroni通过分布式配置存储和健康检查实现主从自动管理。当需要执行计划内维护、硬件替换或版本升级时,不能简单停止主库,否则可能触发不必要的failover,甚至造成数据丢失。Patroni提供的switchover命令可以在受控状态下将主库角色安全地切换到指定从库,整个过程对应用影响最小。

一、switchover 与 failover 的本质区别
Patroni中的failover由故障触发,通常是主库心跳丢失或健康检查失败后,由Patroni自动选择一个合适的从库提升为主库。这个过程追求的是尽快恢复服务,可能不会等待数据完全同步,因此在极端网络分区下存在脑裂或数据丢失风险。switchover则不同,它是由管理员主动发起的计划内切换,Patroni会先确认集群状态,在满足条件时才会变更角色。
角色切换的执行顺序也有明显区别。failover是在旧主库无法参与的情况下强制提升新主库,旧主库恢复后通常需要重新加入集群并作为从库。switchover会先通知旧主库停止接受写入,等待复制链路完成最后的数据同步,然后把候选节点提升为主库,最后把旧主库降级为从库。这样整个切换过程是可预期、可回退的。
从适用场景看,switchover适合版本升级、主机维护、内核参数调整、机房搬迁等计划性操作。failover则用于应对意外宕机、网络断连等紧急情况。管理员应当尽量用switchover替代直接在维护时手动停主库,因为手动停库可能被Patroni判定为故障并触发failover,二者行为差异会直接影响数据安全。
二、执行 switchover 前的检查与准备
执行切换前必须先观察集群整体状态。使用patronictl list命令可以看到每个节点的角色、版本、复制延迟和健康标记。需要确认当前存在一个Leader节点,并且至少有一个健康的从库可以承担主库角色。若从库处于自定义配置、副本落后过多或心跳异常,切换可能失败或者导致业务读到旧数据。
patronictl -c /etc/patroni.yml list
接下来要检查复制延迟。对于同步复制配置,可以通过synchronous_commit和synchronous_standby_names确认从库是否真正参与同步提交。若使用异步复制,切换前应尽量让候选节点与主库延迟接近零。可以用SQL查询pg_stat_replication视图,观察write_lag、flush_lag和replay_lag字段。候选节点最好已经持续应用WAL,不存在明显的重放积压。
此外还需要确认维护窗口、备份策略和应用连接方式。应用应当使用VIP、HAProxy或其他连接代理指向Patroni管理的读/写端点,而不是直连某一个数据库节点。切换完成后,代理层会自动将写入流量指向新主库,减少人工修改连接串的风险。执行前建议完成一次全量备份或至少确认最近备份可恢复。
三、使用 patronictl 执行 switchover 的完整步骤
patronictl提供了交互式切换命令。在命令行中执行patronictl -c /etc/patroni.yml switchover后,Patroni会列出当前集群和节点信息,并询问要切换的集群名称、目标主库和候选节点。交互式操作适合首次使用,但生产环境更推荐使用参数一次性指定,避免误操作。
patronictl -c /etc/patroni.yml switchover
如果希望跳过交互,可以直接指定当前主库和候选节点。下面的命令会把postgres-node1上的主库角色切换到postgres-node2。参数--master表示当前Leader,--candidate表示期望提升的从库。若目标候选节点健康状态不理想,可以追加--force,但生产环境应谨慎使用。
patronictl -c /etc/patroni.yml switchover --master postgres-node1 --candidate postgres-node2
Patroni执行switchover时会先对旧主库执行延迟检查,并尝试通过pg_rewind或复制流完成最终同步。若候选节点不满足提升条件,命令会中止并返回错误,除非指定了强制模式。切换成功后,patronictl list中可以看到新的Leader和新的Replica角色标识。整个过程的超时时间可以通过--timeout参数调整,默认值通常为几分钟,大事务或高负载场景下建议适当增大。
patronictl -c /etc/patroni.yml switchover --master postgres-node1 --candidate postgres-node2 --timeout 120
四、切换过程的日志观察与回滚策略
角色切换过程中可以实时查看Patroni日志。Patroni会在日志中打印健康检查、复制状态、锁竞争以及切换步骤。常见的日志片段包括Lock owner: postgres-node1、Demoting old leader、Promoting candidate和Cleaning up after switchover。如果切换失败,日志通常会指出失败原因,例如候选节点复制延迟过高、目标节点无法连接或同步配置不兼容。
切换完成后需要验证新主库的写入能力。可以连接到新Leader执行写入测试,再检查从库是否继续从新主库接收WAL。若发现切换后业务出现读写异常,应尽快确认代理层是否已经感知到新角色,必要时手动修正连接配置。回滚操作本质上是一次新的switchover,把角色切回原节点,但必须确认旧主库已经重新加入集群并完成数据追赶。
在生产环境中,回滚不一定是最优选择。如果切换后新主库已经产生新增数据,立即切回旧主库可能引入数据冲突。此时应优先修复新主库的异常,而不是盲目回切。管理员需要提前准备好切换预案,明确回滚条件和数据对比方法。
五、通过 REST API 实现自动化 switchover
Patroni在每个节点上暴露REST API,默认端口为8008。通过向/switchover端点发送POST请求,可以在脚本或运维平台中完成切换。请求体通常包含leader和candidate字段。下面是一个使用curl的示例,向127.0.0.1:8008发送切换请求。
curl -s -X POST http://127.0.0.1:8008/switchover \
-H "Content-Type: application/json" \
-d '{"leader":"postgres-node1","candidate":"postgres-node2"}'
如果请求成功,API会返回200状态码,并包含切换任务的信息。如果集群当前不适合切换,API可能返回412 Precondition Failed或503 Service Unavailable,提示候选节点不健康或存在并发操作。自动化脚本需要处理这些返回值,避免在错误时机发起切换。
对于定时维护场景,可以结合cron或CI/CD平台调用API,并配合健康检查接口/health和/cluster获取集群状态。切换前先调用/cluster确认角色分布,满足条件后再调用/switchover。这样可以把计划内切换纳入发布流程,减少人工干预,提升切换的一致性和可审计性。
PatroniswitchoverPostgreSQL高可用修改时间:2026-08-26 13:01:42