2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17
开发版本: devel

29.3. 逻辑复制故障转移 #

为了使订阅者节点在发布者节点宕机时能够继续从发布者节点复制数据,必须有一个对应于发布者节点的物理备用节点。通过在创建订阅时指定 failover = true,可以将主服务器上对应于订阅的逻辑槽同步到备用服务器。有关详细信息,请参阅 第 47.2.3 节。启用 failover 参数可确保在备用节点被提升为主节点后,这些订阅能够无缝切换。它们可以继续订阅新主服务器上的发布。

由于槽同步逻辑是异步复制的,因此在故障转移发生之前,有必要确认复制槽已同步到备用服务器。为了确保故障转移成功,备用服务器必须领先于订阅者。这可以通过配置 synchronized_standby_slots 来实现。

为了确认备用服务器确实已准备好为给定订阅者进行故障转移,请按照以下步骤验证该订阅者所需的所有逻辑复制槽是否已同步到备用服务器。

  1. 在订阅者节点上,使用以下 SQL 来确定哪些复制槽应同步到我们计划提升的备用节点。此查询将返回与启用了故障转移的订阅相关的复制槽。

    /* sub # */ SELECT
                   array_agg(quote_literal(s.subslotname)) AS slots
               FROM  pg_subscription s
               WHERE s.subfailover AND
                     s.subslotname IS NOT NULL;
     slots
    -------
     {'sub1','sub2','sub3'}
    (1 row)
    
  2. 在订阅者节点上,使用以下 SQL 来确定哪些表同步槽应同步到我们计划提升的备用节点。此查询需要在包含启用了故障转移的订阅的每个数据库上运行。请注意,仅当表复制完成后(参见 第 52.55 节),表同步槽才应同步到备用服务器。在其他情况下,我们不需要确保表同步槽已同步,因为它们将在新主服务器上被删除或重新创建。

    /* sub # */ SELECT
                   array_agg(quote_literal(slot_name)) AS slots
               FROM
               (
                   SELECT CONCAT('pg_', srsubid, '_sync_', srrelid, '_', ctl.system_identifier) AS slot_name
                   FROM pg_control_system() ctl, pg_subscription_rel r, pg_subscription s
                   WHERE r.srsubstate = 'f' AND s.oid = r.srsubid AND s.subfailover
               );
     slots
    -------
     {'pg_16394_sync_16385_7394666715149055164'}
    (1 row)
    
  3. 检查上述确定的逻辑复制槽是否存在于备用服务器上并且已准备好进行故障转移。

    /* standby # */ SELECT slot_name, (synced AND NOT temporary AND invalidation_reason IS NULL) AS failover_ready
                   FROM pg_replication_slots
                   WHERE slot_name IN
                       ('sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164');
      slot_name                                 | failover_ready
    --------------------------------------------+----------------
      sub1                                      | t
      sub2                                      | t
      sub3                                      | t
      pg_16394_sync_16385_7394666715149055164   | t
    (4 rows)
    

如果所有槽都存在于备用服务器上,并且上述 SQL 查询的结果(failover_ready)为 true,那么现有订阅可以继续订阅新主服务器上的发布。

上述过程中的前两个步骤是为 PostgreSQL 订阅者设计的。建议在将被指定的备用节点提供服务的每个订阅者节点上运行这些步骤,以获取复制槽的完整列表。然后可以在第 3 步中验证此列表,以确保故障转移就绪。另一方面,非 PostgreSQL 订阅者可能使用自己的方法来识别其各自订阅所使用的复制槽。

在某些情况下,例如在计划的故障转移期间,需要确认所有订阅者(无论是 PostgreSQL 订阅者还是非 PostgreSQL 订阅者)都将能够在新主服务器上继续复制。在这种情况下,请使用以下 SQL(而不是执行上述前两个步骤)来确定主服务器上哪些逻辑复制槽需要同步到计划提升的备用节点。此查询返回与所有启用了故障转移的订阅相关的复制槽。

/* primary # */ SELECT array_agg(quote_literal(r.slot_name)) AS slots
               FROM pg_replication_slots r
               WHERE r.failover AND NOT r.temporary;
 slots
-------
 {'sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164'}
(1 row)

提交更正

如果您在文档中发现任何不正确、与您使用该特定功能时的体验不符或需要进一步澄清的内容,请使用 此表单 来报告文档问题。