

# 使用多可用区数据库集群为 Amazon RDS 设置 PostgreSQL 逻辑复制
<a name="USER_MultiAZDBCluster_LogicalRepl"></a>

通过将 PostgreSQL 逻辑复制与多可用区数据库集群结合使用，您可以复制和同步各个表，而不是整个数据库实例。逻辑复制使用发布和订阅模型将更改从源复制到一个或多个接收者。它的工作原理是使用 PostgreSQL 预写日志（WAL）中的更改记录。有关更多信息，请参阅 [为 Amazon RDS for PostgreSQL 执行逻辑复制](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md)。

当您在多可用区数据库集群的写入器数据库实例上创建新的逻辑复制插槽时，该插槽会异步复制到集群中的每个读取器数据库实例上。读取器数据库实例上的插槽会持续与写入器数据库实例上的插槽同步。

运行 RDS for PostgreSQL 版本 14.8-R2 及更高版本以及 15.3-R2 及更高版本的多可用区数据库集群支持逻辑复制。

**注意**  
除了原生 PostgreSQL 逻辑复制功能外，运行 RDS for PostgreSQL 的多可用区数据库集群还支持 `pglogical` 扩展。

有关 PostgreSQL 逻辑复制的更多信息，请参阅 PostgreSQL 文档中的[逻辑复制](https://www.postgresql.org/docs/current/logical-replication.html)。

**Topics**
+ [先决条件](#multi-az-db-clusters-logical-replication-prereqs)
+ [设置逻辑复制](#multi-az-db-clusters-logical-replication)
+ [限制和建议](#multi-az-db-clusters-logical-replication-limitations)

## 先决条件
<a name="multi-az-db-clusters-logical-replication-prereqs"></a>

要为多可用区数据库集群配置 PostgreSQL 逻辑复制，必须满足以下先决条件。
+ 您的用户账户必须是 `rds_superuser` 组的成员并具有 `rds_superuser` 权限。有关更多信息，请参阅 [了解 PostgreSQL 角色和权限](Appendix.PostgreSQL.CommonDBATasks.Roles.md)。
+ 您的多可用区数据库集群必须与自定义数据库集群参数组相关联，您才能配置以下过程中所述的参数值。有关更多信息，请参阅 [使用多可用区数据库集群的数据库集群参数组](USER_WorkingWithDBClusterParamGroups.md)。

## 设置逻辑复制
<a name="multi-az-db-clusters-logical-replication"></a>

要为多可用区数据库集群设置逻辑复制，请在关联的数据库集群参数组中启用特定参数，然后创建逻辑复制插槽。

**注意**  
从 PostgreSQL 版本 16 开始，您可以使用多可用区数据库集群的读取器数据库实例来进行逻辑复制。

**为 RDS for PostgreSQL 多可用区数据库集群设置逻辑复制**

1. 打开与您的 RDS for PostgreSQL 多可用区数据库集群关联的自定义数据库集群参数组。

1. 在**参数**搜索字段中，找到 `rds.logical_replication` 静态参数并将其值设置为 `1`。此参数更改会增加 WAL 生成，因此只有在使用逻辑插槽时才启用它。

1. 在此更改过程中，请配置以下数据库集群参数。
   + `max_wal_senders`
   + `max_replication_slots`
   + `max_connections`

   根据您的预期使用情况，您可能还需要更改以下参数的值。但是，在许多情况下，原定设置值就足够了。
   + `max_logical_replication_workers`
   + `max_sync_workers_per_subscription`

1. 重启多可用区数据库集群以使参数值生效。有关说明，请参阅[重启 Amazon RDS 的多可用区数据库集群和读取器数据库实例](multi-az-db-clusters-concepts-rebooting.md)。

1. 如[使用逻辑复制槽](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md#PostgreSQL.Concepts.General.FeatureSupport.LogicalReplicationSlots)中所述，在多可用区数据库集群的写入器数据库实例上创建逻辑复制插槽。该过程需要您指定解码插件。目前，RDS for PostgreSQL 支持 PostgreSQL 随附的 `test_decoding`、`wal2json` 和 `pgoutput` 插件。

   该插槽会异步复制到集群中的每个读取器数据库实例。

1. 验证多可用区数据库集群所有读取器数据库实例上的插槽状态。为此，请检查所有读取器数据库实例上的 `pg_replication_slots` 视图，并确保在应用程序积极使用逻辑更改时，状态 `confirmed_flush_lsn` 推进。

   以下命令演示了如何检查读取器数据库实例上的复制状态。

   ```
   % psql -h test-postgres-instance-2.abcdefabcdef.us-west-2.rds.amazonaws.com
   
   postgres=> select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
     slot_name   | slot_type | confirmed_flush_lsn
   --------------+-----------+---------------------
    logical_slot | logical   | 32/D0001700
   (1 row)
   
   postgres=> select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
     slot_name   | slot_type | confirmed_flush_lsn
   --------------+-----------+---------------------
    logical_slot | logical   | 32/D8003628
   (1 row)
   
   % psql -h test-postgres-instance-3.abcdefabcdef.us-west-2.rds.amazonaws.com
   
   postgres=> select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
     slot_name   | slot_type | confirmed_flush_lsn
   --------------+-----------+---------------------
    logical_slot | logical   | 32/D0001700
   (1 row)
   
   postgres=> select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
     slot_name   | slot_type | confirmed_flush_lsn
   --------------+-----------+---------------------
    logical_slot | logical   | 32/D8003628
   (1 row)
   ```

完成复制任务后，停止复制过程，删除复制插槽并关闭逻辑复制。要关闭逻辑复制，请修改您的数据库集群参数组并将 `rds.logical_replication` 的值设回 `0`。重启集群以使参数更改生效。

## 限制和建议
<a name="multi-az-db-clusters-logical-replication-limitations"></a>

在使用运行 PostgreSQL 16 的多可用区数据库集群进行逻辑复制时，以下限制和建议适用：
+ 您只能使用写入器数据库实例来创建或删除逻辑复制槽。例如，`CREATE SUBSCRIPTION` 命令必须在主机连接字符串中使用集群写入器端点。
+ 在任何表同步或再同步期间，您都必须使用集群写入器端点。例如，您可以使用以下命令来再同步新添加的表。

  ```
  Postgres=>ALTER SUBSCRIPTION subscription-name CONNECTION host=writer-endpoint
  Postgres=>ALTER SUBSCRIPTION subscription-name REFRESH PUBLICATION
  ```
+ 在使用读取器数据库实例进行逻辑复制之前，必须等待表完成同步。您可以使用 `[pg\$1subscription\$1rel](https://www.postgresql.org/docs/current/catalog-pg-subscription-rel.html)` 目录表来监控表同步。当 `srsubstate` 列设置为就绪（`r`）时，表示表同步已完成。
+ 建议您在初始表同步完成后使用实例端点进行逻辑复制连接。以下命令通过将复制载荷分流到一个读取器数据库实例，来减少写入器数据库实例的载荷:

  ```
  Postgres=>ALTER SUBSCRIPTION subscription-name CONNECTION host=reader-instance-endpoint
  ```

  您不能同时在多个数据库实例上使用相同的复制槽。当两个或更多应用程序从集群中的不同数据库实例复制逻辑更改时，某些更改可能由于集群失效转移或网络问题而丢失。在此类情况下，您可以使用实例端点在主机连接字符串中进行逻辑复制。使用相同配置的另一个应用程序将显示以下错误消息：

  ```
  replication slot slot_name is already active for PID x providing immediate feedback.
  ```
+ 使用 `pglogical` 扩展时，您只能使用集群写入器端点。该扩展具有已知的局限性，可能会在表同步期间创建未使用的逻辑复制槽。过时的复制槽会保留预写日志（WAL）文件，并可能导致磁盘空间问题。