PostgreSQL 17: 逻辑复制支持故障转移

John Doe 十月 24, 2025

在 PostgreSQL 逻辑复制架构中,“故障转移后数据同步的连续性”一直是运维痛点。此前发布端的复制槽不会同步到备库,一旦主库故障、备库升为新主库,原订阅端因缺失复制槽信息,无法继续同步数据,需手动重建槽并校验数据一致性,不仅耗时,还可能因操作失误导致数据丢失。

image

特性提交日志

为订阅添加故障转移(failover)选项。

本次提交为订阅新增了一个名为 “failover” 的选项,该选项允许用户在创建或修改订阅时,设置发布端上复制槽的故障转移属性。

此功能借助提交 7329240437 引入的复制命令,为逻辑复制槽启用了故障转移选项。

若将 failover 选项设为 true,上游数据库中关联的复制槽(即主复制槽和表同步槽)将被允许同步到备库。

讨论:https://postgr.es/m/514f6f2f-6833-4539-39f1-96cd1e011f23@enterprisedb.com

示例

在该特性推出前,PostgreSQL 逻辑复制的故障转移流程存在两大关键局限:

  1. 复制槽无法跨主备同步:发布端的主复制槽(用于接收全量+增量数据)和表同步槽(用于单表初始化同步)仅存在于主库,备库没有这些槽的元数据。当主库宕机、备库升主后,原订阅端因找不到对应的复制槽,同步会直接中断。
  2. 故障恢复成本高且易出错:恢复同步需手动在新主库重建复制槽,且需精确指定原同步位置(LSN),否则可能导致数据重复或丢失;若涉及多表同步,还需逐一校验表数据一致性,运维成本极高。

此次新增的failover选项,通过标记复制槽“可同步到备库”,为后续“主备复制槽自动同步”提供基础,最终实现故障转移后“零手动操作”恢复同步。

可通过下面的 SQL 查看订阅的failover状态:

-- 查看所有订阅的 failover 配置
SELECT subname, subslotname, subfailover
FROM pg_subscription;

确认发布端配置:确保发布端主库(pg-primary)已创建包含user_account表的发布(如pub_user):

-- 发布端主库执行:创建发布
CREATE PUBLICATION pub_user FOR TABLE user_account;

订阅端创建带failover的订阅:

-- 订阅端执行:创建订阅并启用 failover
CREATE SUBSCRIPTION sub_user_account
CONNECTION 'host=pg-primary port=5432 dbname=finance user=repl password=Repl@123'
PUBLICATION pub_user
WITH (
  create_slot = true,  -- 自动在发布端创建复制槽
  enabled = true,      -- 创建后立即启用同步
  failover = true      -- 启用复制槽的备库同步能力
);
  • 若设置connect = false(创建订阅时不连接发布端),则failover必须为false。因为不连接发布端无法创建复制槽,自然无需配置槽的同步能力。
  • 必须同时设置create_slot = true(或使用已存在的复制槽slot_name),否则failover无意义(无复制槽可关联)。

非常不错的改进,感谢社区的所有相关人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/776621a5e4796fa214b6b29a7ca134f6c138572a