

# 在主要升级后重新建立逻辑复制
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade"></a>

对于设置为逻辑复制的发布者节点的 RDS for PostgreSQL 数据库实例，在可以对其执行主要版本升级之前，您必须删除所有复制插槽，即使是不活动的复制插槽也是如此。我们建议您暂时从发布者节点转移数据库事务，删除复制插槽，升级 RDS for PostgreSQL 数据库实例，然后重新建立并重新启动复制。

复制插槽仅托管在发布者节点上。逻辑复制场景中的 RDS for PostgreSQL 订阅者节点没有可删除的插槽，但当它被指定为对发布者具有订阅的订阅者节点时，它无法升级到主要版本。在升级 RDS for PostgreSQL 订阅者节点之前，请删除订阅和节点。有关更多信息，请参阅。[管理 RDS for PostgreSQL 的逻辑复制插槽](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)

## 确定逻辑复制已中断
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.identifying-the-issue"></a>

您可以通过查询发布者节点或订阅者节点来确定复制过程是否已中断，如下所示。

**检查发布者节点**
+ 使用 `psql` 连接到发布者节点，然后查询 `pg_replication_slots` 函数。注意活动列中的值。通常，这将返回 `t`（true），表明复制处于活动状态。如果查询返回 `f`（false），则表明向订阅者的复制已停止。

  ```
  SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
                      slot_name              |      plugin      | slot_type | active
  -------------------------------------------+------------------+-----------+--------
   pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical   | f
  (1 row)
  ```

**检查订阅者节点**

在订阅者节点上，您可以通过三种不同的方式检查复制的状态。
+ 浏览订阅者节点上的 PostgreSQL 日志，以查找失败消息。该日志使用包含退出代码 1 的消息来标识故障，如下所示。

  ```
  2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1
  2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
  ```
+ 查询 `pg_replication_origin` 函数。使用 `psql` 连接到订阅者节点上的数据库并查询 `pg_replication_origin` 函数，如下所示。

  ```
  SELECT * FROM pg_replication_origin;
   roident | roname
  ---------+--------
  (0 rows)
  ```

  结果集为空表示复制已中断。正常情况下，您将看到如下输出。

  ```
     roident |                       roname
    ---------+----------------------------------------------------
           1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
    (1 row)
  ```
+ 查询 `pglogical.show_subscription_status` 函数，如以下示例所示。

  ```
  SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
       subscription_name | status |              slot_name
  ---====----------------+--------+-------------------------------------
   docs_lab_subscription | down   | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
  (1 row)
  ```

  此输出显示复制已中断。它的状态为 `down`。通常，输出将状态显示为 `replicating`。

如果您的逻辑复制过程已中断，则可以按照以下步骤重新建立复制。

**在发布者节点和订阅者节点之间重新建立逻辑复制**

要重新建立复制，请先断开订阅者与发布者节点的连接，然后重新建立订阅，如这些步骤所述。

1. 使用 `psql` 连接到订阅者节点，如下所示。

   ```
   psql --host=222222222222.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 通过使用 `pglogical.alter_subscription_disable` 函数停用订阅。

   ```
   SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true);
    alter_subscription_disable
   ----------------------------
    t
   (1 row)
   ```

1. 通过查询 `pg_replication_origin` 获取发布者节点的标识符，如下所示。

   ```
   SELECT * FROM pg_replication_origin;
    roident |               roname
   ---------+-------------------------------------
          1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
   (1 row)
   ```

1. 将上一步的响应与 `pg_replication_origin_create` 命令一起使用，以分配重新建立时订阅可以使用的标识符。

   ```
   SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c');
     pg_replication_origin_create
   ------------------------------
                               1
   (1 row)
   ```

1. 通过传递其状态为 `true` 的名称来打开订阅，如下面的示例所示。

   ```
   SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true);
     alter_subscription_enable
   ---------------------------
    t
   (1 row)
   ```

检查节点的状态。其状态应为 `replicating`，如本例所示。

```
SELECT subscription_name,status,slot_name
  FROM pglogical.show_subscription_status();
             subscription_name |   status    |              slot_name
-------------------------------+-------------+-------------------------------------
 docs_lab_subscription         | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c
(1 row)
```

检查发布者节点上订阅者的复制插槽的状态。插槽的 `active` 列应返回 `t`（true），表示已重新建立复制。

```
SELECT slot_name,plugin,slot_type,active
  FROM pg_replication_slots;
                    slot_name              |      plugin      | slot_type | active
-------------------------------------------+------------------+-----------+--------
 pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical   | t
(1 row)
```