受支持版本: 当前版本 (18) / 17 / 15
开发版本: devel

29.3. 逻辑复制故障切换 #

为了让订阅节点在发布节点宕机后仍能继续从发布端复制数据,发布节点必须有对应的 物理备库。创建订阅时指定 failover = true,即可将主库上与 订阅对应的逻辑槽同步到备库。详情见 Section 47.2.3。 启用 failover 参数可确保备库提升后这些订阅无缝切换,并继续订阅新主库上的发布。

由于槽同步逻辑是异步复制,在发生故障切换前,必须确认复制槽已经同步到备库。 为确保故障切换成功,备库必须领先于订阅端。可通过配置 synchronized_standby_slots 实现。

要确认某个订阅对应的备库确实已做好故障切换准备,请按下列步骤验证该订阅需要的 所有逻辑复制槽都已同步到备库:

  1. 在订阅节点上,使用以下 SQL 识别应同步到计划提升的备库的复制槽。 该查询返回启用故障切换的订阅对应的复制槽。

    test_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 识别应同步到计划提升备库的表同步槽。 此查询需要在每个包含启用故障切换订阅的数据库中执行。 注意只有在表复制完成时,表同步槽才应同步到备库(见 Section 51.55)。 在其他场景下无需确保表同步槽已同步,因为这些情况下它们会在新主库上被删除或重建。

    test_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. 检查上面识别出的逻辑复制槽是否存在于备库上,并且已准备好故障切换。

    test_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)在切换到某个备库后都能继续复制。 这种情况下,可用下列 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)

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。