

# 使用逻辑复制对 Aurora PostgreSQL 执行主要版本升级
<a name="AuroraPostgreSQL.MajorVersionUpgrade"></a>

使用逻辑复制和 Aurora 快速克隆，您可以执行使用当前版本 Aurora PostgreSQL 数据库的主要版本升级，同时将不断变化的数据逐渐迁移到新的主要版本数据库。这种停机时间短的升级过程称为蓝绿升级。数据库的当前版本称为“蓝色”环境，新的数据库版本称为“绿色”环境。

Aurora 快速克隆通过拍摄源数据库的快照来完全加载现有数据。快速克隆使用构建在 Aurora 存储层之上的写入时复制协议，这可让您在短时间内创建数据库的克隆。升级到大型数据库时，此方法非常有效。

PostgreSQL 中的逻辑复制会跟踪您的数据更改，并将其从初始实例传输到并行运行的新实例，直到您移至 PostgreSQL 的更新版本。逻辑复制使用发布和订阅模型。有关 Aurora PostgreSQL 逻辑复制的更多信息，请参阅[使用 Amazon Aurora PostgreSQL 进行复制](AuroraPostgreSQL.Replication.md)。

**提示**  
您可以使用托管式 Amazon RDS 蓝绿部署功能，最大限度地减少主要版本升级所需的停机时间。有关更多信息，请参阅 [使用 Amazon Aurora 蓝绿部署进行数据库更新](blue-green-deployments.md)。

**Topics**
+ [要求](#AuroraPostgreSQL.MajorVersionUpgrade.Requirements)
+ [限制](#AuroraPostgreSQL.MajorVersionUpgrade.Limitations)
+ [设置和检查参数值](#AuroraPostgreSQL.MajorVersionUpgrade.Parameters)
+ [将 Aurora PostgreSQL 升级到新的主要版本](#AuroraPostgreSQL.MajorVersionUpgrade.StartLogicalReplication)
+ [执行升级后任务](#AuroraPostgreSQL.MajorVersionUpgrade.PostUpgrade)

## 要求
<a name="AuroraPostgreSQL.MajorVersionUpgrade.Requirements"></a>

必须满足以下要求，才能执行这一停机时间短的升级过程：
+ 您必须拥有 rds\$1superuser 权限。
+ 您打算升级的 Aurora PostgreSQL 数据库集群必须运行支持的版本，该版本可以使用逻辑复制执行主要版本升级。确保将任何次要版本更新和补丁应用于数据库集群。以下版本的 Aurora PostgreSQL 支持此技术中使用的 `aurora_volume_logical_start_lsn` 函数：
  + 15.2 及更高的 15 版本
  + 14.3 及更高的 14 版本
  + 13.6 及更高的 13 版本
  + 12.10 及更高的 12 版本
  + 11.15 及更高的 11 版本
  + 10.20 及更高的 10 版本

  有关 `aurora_volume_logical_start_lsn` 函数的更多信息，请参阅[aurora\$1volume\$1logical\$1start\$1lsn](aurora_volume_logical_start_lsn.md)。
+ 您的所有表都必须具有主键或包含 [PostgreSQL 标识列](https://www.postgresql.org/docs/current/sql-createtable.html)。
+ 为您的 VPC 配置安全组，以允许两个 Aurora PostgreSQL 数据库集群（包括新旧集群）之间的入站和出站访问。您可以授予对特定的无类别域间路由（CIDR）范围的访问权限，或对 VPC 或对等 VPC 中另一个安全组的访问权限。（对等 VPC 要求 VPC 对等连接。）

**注意**  
有关配置和管理正在运行的逻辑复制场景所需的权限的详细信息，请参阅 [PostgreSQL 核心文档](https://www.postgresql.org/docs/13/logical-replication-security.html)。

## 限制
<a name="AuroraPostgreSQL.MajorVersionUpgrade.Limitations"></a>

 当您在 Aurora PostgreSQL 数据库集群上执行停机时间短的升级以将其升级到新的主要版本时，您使用的是原生 PostgreSQL 逻辑复制功能。它具有与 PostgreSQL 逻辑复制相同的功能和限制。有关更多信息，请参阅 [PostgreSQL 逻辑复制](https://www.postgresql.org/docs/13/logical-replication.html)。
+ 不复制数据定义语言（DDL）命令。
+ 复制不支持在实时数据库中进行模式更改。在克隆过程中，将以其原始形式重新创建模式。如果您在克隆之后但在完成升级之前更改模式，则该模式不会反映在升级后的实例中。
+ 无法复制大型对象，但您可以将数据存储在普通表中。
+ 只有表（包括分区表）支持复制。不支持复制到其他类型的关系，例如视图、实例化视图或外部表。
+ 未复制序列数据，需要在失效转移后手动更新。

**注意**  
此升级不支持自动脚本编写。您应该手动执行所有步骤。

## 设置和检查参数值
<a name="AuroraPostgreSQL.MajorVersionUpgrade.Parameters"></a>

 升级之前，将您的 Aurora PostgreSQL 数据库集群的写入器实例配置为发布服务器。实例应使用具有以下设置的自定义数据库集群参数组：
+ `rds.logical_replication` – 将该参数设置为 1。`rds.logical_replication` 参数的用途与独立 PostgreSQL 服务器的 `wal_level` 参数以及其他控制预写日志文件管理的参数相同。
+ `max_replication_slots` – 将此参数设置为您计划创建的订阅总数。如果您使用 AWS DMS，请将此参数设置为您计划用于从此数据库集群中捕获更改数据的 AWS DMS 任务数。
+ `max_wal_senders` – 设置为并发连接数，加上几个额外连接，以供管理任务和新会话使用。如果您使用的是 AWS DMS，max\$1wal\$1senders 的数量应等于并发会话数加上在任何给定时间可能正在运行的 AWS DMS 任务数。
+ `max_logical_replication_workers` – 设置为您预期的逻辑复制工作线程和表同步工作线程的数量。通常，将复制工作线程的数量设置为用于 max\$1wal\$1senders 的相同值是安全的。工作进程取自为服务器分配的后台进程池（max\$1worker\$1processes）。
+  `max_worker_processes` – 设置为服务器的后台进程数。这个数字应该足够大，足以为复制、自动清理过程和其他可能同时进行的维护过程分配工作线程。

升级到 Aurora PostgreSQL 的更高版本时，您需要复制您在参数组的早期版本中修改的任何参数。这些参数应用于升级后的版本。您可以查询 `pg_settings` 表以获取参数设置列表，以便可以在新的 Aurora PostgreSQL 数据库集群上重新创建这些设置。

例如，要获取复制参数的设置，请运行以下查询：

```
SELECT name, setting FROM pg_settings WHERE name in 
('rds.logical_replication', 'max_replication_slots', 
'max_wal_senders', 'max_logical_replication_workers', 
'max_worker_processes');
```

## 将 Aurora PostgreSQL 升级到新的主要版本
<a name="AuroraPostgreSQL.MajorVersionUpgrade.StartLogicalReplication"></a>

**让发布者做好准备（蓝色）**

1. 在下面的示例中，源写入器实例（蓝色）是运行 PostgreSQL 版本 11.15 的 Aurora PostgreSQL 数据库集群。这是我们复制场景中的发布节点。对于本演示，我们的源代码编写器实例托管了一个包含一系列值的示例表：

   ```
   CREATE TABLE my_table (a int PRIMARY KEY);
   INSERT INTO my_table VALUES (generate_series(1,100));
   ```

1. 要在源实例上创建发布，请使用 psql（PostgreSQL 的 CLI）或您选择的客户端连接到该实例的写入器节点。在每个数据库中输入以下命令：

   ```
   CREATE PUBLICATION publication_name FOR ALL TABLES;
   ```

   publication\$1name 指定发布的名称。

1. 您还需要在实例上创建复制插槽。以下命令创建复制插槽并加载 `pgoutput` [逻辑解码插件](https://www.postgresql.org/docs/current/logicaldecoding-explanation.html)。该插件将读取的内容从预写日志（WAL）更改为逻辑复制协议，并根据发布规范筛选数据。

   ```
   SELECT pg_create_logical_replication_slot('replication_slot_name', 'pgoutput');
   ```

**克隆发布者**

1. 使用 Amazon RDS 控制台创建源实例的克隆。在 Amazon RDS 控制台中突出显示实例名称，然后在 **Actions**（操作）菜单中选择 **Create clone**（创建克隆）。  
![\[Aurora MySQL 数据库集群从版本 2 就地升级到版本 3\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/images/apg-logicalreplication-mvu-create-clone.png)

1. 为实例提供唯一名称。大多数设置是源实例中的缺省设置。当您对新实例进行了所需的更改后，选择 **Create clone**（创建克隆）。  
![\[Aurora MySQL 数据库集群从版本 2 就地升级到版本 3\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/images/apg-logicalreplication-mvu-create-clone-note.png)

1. 当目标实例启动时，写入器节点的 **Status**（状态）列在 **Status**（状态）列中显示 Creating（正在创建）。在实例准备就绪后，状态将变为 Available（可用）。

**为升级准备克隆**

1. 克隆是部署模型中的“绿色”实例。它是复制订阅节点的主机。当节点变为可用时，连接 psql 并查询新的写入器节点以获取日志序列号（LSN）。LSN 标识 WAL 流中记录的开头。

   ```
   SELECT aurora_volume_logical_start_lsn();
   ```

1. 在查询的响应中，您可以找到 LSN 编号。您稍后在此过程中需要这个编号，所以请记下它。

   ```
   postgres=> SELECT aurora_volume_logical_start_lsn();
   aurora_volume_logical_start_lsn 
   ---------------
   0/402E2F0
   (1 row)
   ```

1. 在升级克隆之前，删除克隆的复制插槽。

   ```
   SELECT pg_drop_replication_slot('replication_slot_name');
   ```

**将集群升级到新的主要版本**
+ 在克隆提供商节点时，请使用 Amazon RDS 控制台在订阅节点上启动主要版本升级。在 RDS 控制台中突出显示实例名称，然后选择 **Modify**（修改）按钮。选择更新的版本和更新的参数组，然后立即应用设置来升级目标实例。  
![\[Aurora MySQL 数据库集群从版本 2 就地升级到版本 3\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/images/apg-logicalreplication-mvu-modify-DB-cluster.png)
+ 还可以使用 CLI 来执行升级：

  ```
  aws rds modify-db-cluster —db-cluster-identifier $TARGET_Aurora_ID —engine-version 13.6 —allow-major-version-upgrade —apply-immediately
  ```

**让订阅者做好准备（绿色）**

1. 当升级后克隆变为可用时，连接到 psql 并定义订阅。为此，您需要在 `CREATE SUBSCRIPTION` 命令中指定以下选项：
   + `subscription_name` – 订阅的名称。
   + `admin_user_name` – 拥有 rds\$1superuser 权限的管理用户的名称。
   + `admin_user_password` – 与管理用户关联的密码。
   + `source_instance_URL` – 发布服务器实例的 URL。
   + `database` – 订阅服务器将与之连接的数据库。
   + `publication_name` – 发布服务器的名称。
   + `replication_slot_name` – 复制插槽的名称。

   ```
   CREATE SUBSCRIPTION subscription_name 
   CONNECTION 'postgres://admin_user_name:admin_user_password@source_instance_URL/database' PUBLICATION publication_name 
   WITH (copy_data = false, create_slot = false, enabled = false, connect = true, slot_name = 'replication_slot_name');
   ```

1.  创建订阅后，查询 [pg\$1replication\$1origin](https://www.postgresql.org/docs/14/catalog-pg-replication-origin.html) 视图以检索 roname 值，该值是复制源的标识符。每个实例都有一个 `roname`：

   ```
   SELECT * FROM pg_replication_origin;
   ```

   例如：

   ```
   postgres=> 
   SELECT * FROM pg_replication_origin;
    
   roident | roname 
   ---------+----------
   1 | pg_24586
   ```

1. 在命令中提供您在发布节点的先前查询中保存的 LSN 以及从订阅节点 [实例]返回的 `roname`。此命令使用 `[pg\$1replication\$1origin\$1advance](https://www.postgresql.org/docs/14/functions-admin.html)` 函数指定要复制的日志序列的起点。

   ```
   SELECT pg_replication_origin_advance('roname', 'log_sequence_number');
   ```

   `roname` 是 pg\$1replication\$1origin 视图返回的标识符。

   `log_sequence_number` 是 `aurora_volume_logical_start_lsn` 函数的先前查询返回的值。

1. 然后，使用 `ALTER SUBSCRIPTION... ENABLE` 子句开启逻辑复制。

   ```
   ALTER SUBSCRIPTION subscription_name ENABLE;
   ```

1. 此时，您可以确认复制正在运行。向发布实例添加一个值，然后确认该值已复制到订阅节点。

   然后，使用以下命令监控发布节点上的复制滞后：

   ```
   SELECT now() AS CURRENT_TIME, slot_name, active, active_pid, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),
   confirmed_flush_lsn)) AS diff_size, pg_wal_lsn_diff(pg_current_wal_lsn(),
   confirmed_flush_lsn) AS diff_bytes FROM pg_replication_slots WHERE slot_type = 'logical';
   ```

   例如：

   ```
   postgres=> SELECT now() AS CURRENT_TIME, slot_name, active, active_pid, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), 
   confirmed_flush_lsn)) AS diff_size, pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn) AS diff_bytes FROM pg_replication_slots WHERE slot_type = 'logical';
    
   current_time                   | slot_name             | active | active_pid | diff_size | diff_bytes 
   -------------------------------+-----------------------+--------+------------+-----------+------------
   2022-04-13 15:11:00.243401+00  | replication_slot_name | t      | 21854      | 136 bytes | 136
   (1 row)
   ```

   您可以使用 `diff_size` 和 `diff_bytes` 值监控复制滞后。当这些值达到 0 时，即表示副本已赶上源数据库实例进度。

## 执行升级后任务
<a name="AuroraPostgreSQL.MajorVersionUpgrade.PostUpgrade"></a>

升级完成后，实例状态在控制台控制面板的 **Status**（状态）列中显示为 **Available**（可用）。在新实例上，建议您执行以下操作：
+ 重定向应用程序以指向写入器节点。
+ 添加读取器节点以管理案例量，并在写入器节点出现问题时提供高可用性。
+ Aurora PostgreSQL 数据库集群偶尔需要操作系统更新。这些更新可能包含较新版本的 glibc 库。在此类更新期间，我们建议您遵循 [Aurora PostgreSQL 中支持的排序规则](PostgreSQL-Collations.md)中所述的指南。
+ 更新用户对新实例的权限以确保访问权限。

在新实例上测试应用程序和数据后，我们建议您在删除初始实例之前对其进行最终备份。有关在 Amazon 主机上使用逻辑复制的更多信息，请参阅 [为 Aurora PostgreSQL 数据库集群设置逻辑复制](AuroraPostgreSQL.Replication.Logical.Configure.md)。