

# 只读副本上的逻辑解码
<a name="USER_PostgreSQL.Replication.ReadReplicas.LogicalDecoding"></a>

 RDS for PostgreSQL 支持使用 PostgreSQL 16.1 从备用数据库实例进行逻辑复制。这允许您从只读备用数据库实例创建逻辑解码，从而减少主数据库实例上的负载。对于需要在多个系统之间同步数据的应用程序，您可以实现更高的可用性。此功能可提高数据仓库和数据分析的性能。

 此外，给定备用数据库实例上的复制插槽会持续将该备用数据库实例提升为主数据库实例。这意味着，如果主数据库实例发生失效转移或将备用数据库实例提升为新的主数据库实例，则复制插槽将持续存在，以前的备用数据库实例订阅用户不会受到影响。

**在只读副本上创建逻辑解码**

1. **开启逻辑复制** - 要在备用数据库实例上创建逻辑解码，您必须在源数据库实例及其物理副本上启用逻辑复制。有关更多信息，请参阅 [PostgreSQL 只读副本配置](USER_PostgreSQL.Replication.ReadReplicas.Configuration.md)。
   + **为新创建的 RDS for PostgreSQL 数据库实例启用逻辑复制** – 创建新的数据库自定义参数组，并将静态参数 `rds.logical_replication` 设置为 `1`。然后，将此数据库参数组与源数据库实例及其物理只读副本相关联。有关更多信息，请参阅 [在 Amazon RDS 中将数据库参数组与数据库实例关联](USER_WorkingWithParamGroups.Associating.md)。
   + **为现有 RDS for PostgreSQL 数据库实例开启逻辑复制** – 修改源数据库实例及其物理只读副本的数据库自定义参数组，以将静态参数 `rds.logical_replication` 设置为 `1`。有关更多信息，请参阅 [在 Amazon RDS 中修改数据库参数组中的参数](USER_WorkingWithParamGroups.Modifying.md)。
**注意**  
必须重启数据库实例才能应用这些参数更改。

   您可以使用以下查询来验证源数据库实例及其物理只读副本上的 `wal_level` 和 `rds.logical_replication` 值。

   ```
   Postgres=>SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication');
               
    name                    | setting 
   -------------------------+---------
    rds.logical_replication | on
    wal_level               | logical
   (2 rows)
   ```

1. **在源数据库中创建表** – 连接到源数据库实例中的数据库。有关更多信息，请参阅 [连接到运行 PostgreSQL 数据库引擎的数据库实例](USER_ConnectToPostgreSQLInstance.md)。

   使用以下查询在源数据库中创建表并插入值：

   ```
   Postgres=>CREATE TABLE LR_test (a int PRIMARY KEY);
   CREATE TABLE
   ```

   ```
   Postgres=>INSERT INTO LR_test VALUES (generate_series(1,10000));
   INSERT 0 10000
   ```

1. **为源表创建发布** - 使用以下查询为源数据库实例上的表创建发布。

   ```
   Postgres=>CREATE PUBLICATION testpub FOR TABLE LR_test;
   CREATE PUBLICATION
   ```

   使用 SELECT 查询来验证在源数据库实例和物理只读副本实例上创建的发布的详细信息。

   ```
   Postgres=>SELECT * from pg_publication;
                
   oid    | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot 
   -------+---------+----------+--------------+-----------+-----------+-----------+-------------+------------
    16429 | testpub |    16413 | f            | t         | t         | t         | t           | f
   (1 row)
   ```

1. **从逻辑副本实例创建订阅** – 创建另一个 RDS for PostgreSQL 数据库实例作为逻辑副本实例。确保 VPC 设置正确，以确保此逻辑副本实例可以访问物理只读副本实例。有关更多信息，请参阅 [Amazon VPC 和 Amazon RDS](USER_VPC.md)。如果您的源数据库实例处于空闲状态，则可能会出现连接问题，并且主数据库实例不会将数据发送到备用数据库实例。

   ```
   Postgres=>CREATE SUBSCRIPTION testsub CONNECTION 'host={{Physical replica host name}} port={{port}} 
                   dbname={{source_db_name}} user={{user}} password={{password}}' PUBLICATION {{testpub;}}
   NOTICE:  created replication slot "testsub" on publisher
   CREATE SUBSCRIPTION
   ```

   ```
   Postgres=>CREATE TABLE LR_test (a int PRIMARY KEY);
   CREATE TABLE
   ```

   使用 SELECT 查询来验证逻辑副本实例上的订阅详细信息。

   ```
   Postgres=>SELECT oid,subname,subenabled,subslotname,subpublications FROM pg_subscription;
               
   oid    | subname | subenabled | subslotname | subpublications 
   -------+---------+------------+-------------+-----------------
    16429 | testsub | t          | testsub     | {testpub}
   (1 row)
   postgres=> select count(*) from LR_test;
    count 
   -------
    10000
   (1 row)
   ```

1. **检查逻辑复制插槽状态** - 您只能看到源数据库实例上的物理复制插槽。

   ```
   Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
               
   slot_name                                    | slot_type | confirmed_flush_lsn 
   ---------------------------------------------+-----------+---------------------
    rds_us_west_2_db_dhqfsmo5wbbjqrn3m6b6ivdhu4 | physical  | 
   (1 row)
   ```

   但是，在您的只读副本实例上，您可以看到逻辑复制插槽和 `confirmed_flush_lsn` 值会随着应用程序主动使用逻辑更改而发生变化。

   ```
   Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
               
   slot_name | slot_type | confirmed_flush_lsn 
   -----------+-----------+---------------------
    testsub   | logical   | 0/500002F0
   (1 row)
   ```

   ```
   Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
               
   slot_name | slot_type | confirmed_flush_lsn 
   -----------+-----------+---------------------
    testsub   | logical   | 0/5413F5C0
   (1 row)
   ```