

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在重大升級之後重新建立邏輯複寫
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade"></a>

在對設為邏輯複寫之發佈者節點的 Aurora PostgreSQL 資料庫叢集執行主要版本升級之前，您必須捨棄所有複寫槽，即使是未作用中的複寫槽也一樣。建議您暫時從發佈者節點轉移資料庫交易、捨棄複寫槽、升級 Aurora PostgreSQL 資料庫叢集，然後重新建立並重新啟動複寫。

複寫槽僅託管於發佈者節點上。邏輯複寫案例中的 Aurora PostgreSQL 訂閱者節點沒有要捨棄的複寫槽。Aurora PostgreSQL 主要版本升級程序支援將訂閱者獨立升級至與發佈者節點不同的新主要 PostgreSQL 版本。不過，升級程序確實會中斷複寫程序，並干擾發佈者節點與訂閱者節點之間的 WAL 資料同步。在升級發佈者、訂閱者或兩者之後，您必須重新建立發佈者與訂閱者之間的邏輯複寫。下列程序說明如何判斷複寫是否已中斷，以及如何解決問題。

## 判斷邏輯複寫是否已中斷
<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)
```