

# 执行主要版本升级
<a name="USER_UpgradeDBInstance.PostgreSQL.MajorVersion"></a>

主要版本升级可能包含不与数据库的以前版本向后兼容的数据库更改。新版本中的新功能会导致现有应用程序停止正常工作。为避免出现问题，Amazon Aurora 不会自动应用主要版本升级。相反，我们建议您按照以下步骤仔细规划主要版本升级：

1. 从表中为您的版本列出的可用目标列表中选择所需的主要版本。通过使用 AWS CLI，您可以获得您的 AWS 区域中针对当前版本推出的版本的精确列表。有关更多信息，请参阅 [获取您的 AWS 区域中可用版本的列表](USER_UpgradeDBInstance.PostgreSQL.UpgradeVersion.md)。

1. 验证您的应用程序在新版本的试用部署中是否按预期工作。有关完整过程的信息，请参阅[测试将生产数据库集群升级到新的主要版本](#USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Upgrade.preliminary)。

1. 在验证应用程序在试用部署中按预期工作后，您可以升级集群。有关更多信息，请参阅 [将 Aurora PostgreSQL 引擎升级到新的主要版本](#USER_UpgradeDBInstance.Upgrading.Manual)。

**注意**  
您可以执行主要版本升级，以从基于适用于 Aurora PostgreSQL 的 Babelfish 13 的版本（从 13.6 开始）升级到基于 Aurora PostgreSQL 14 的版本（从 14.6 开始）。适用于 Aurora PostgreSQL 的 Babelfish 13.4 和 13.5 不支持主要版本升级。

通过查询 AWS 区域并使用 AWS CLI 命令 [describe-db-engine-versions](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html)，您可以获得可用作 Aurora PostgreSQL 数据库集群的主要版本升级目标的引擎版本列表，如下所示。

对于 Linux、macOS 或 Unix：

```
aws rds describe-db-engine-versions \
  --engine aurora-postgresql \
  --engine-version version-number \
  --query 'DBEngineVersions[].ValidUpgradeTarget[?IsMajorVersionUpgrade == `true`].{EngineVersion:EngineVersion}' \
  --output text
```

对于：Windows

```
aws rds describe-db-engine-versions ^
  --engine aurora-postgresql ^
  --engine-version version-number ^
  --query "DBEngineVersions[].ValidUpgradeTarget[?IsMajorVersionUpgrade == `true`].{EngineVersion:EngineVersion}" ^
  --output text
```

在某些情况下，要升级到的版本不是当前版本的目标。在这种情况下，请使用[versions table](USER_UpgradeDBInstance.PostgreSQL.UpgradeVersion.md#versions-table)中的信息执行次要版本升级，直到您的集群处于其目标行中包含所选目标的版本。

## 测试将生产数据库集群升级到新的主要版本
<a name="USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Upgrade.preliminary"></a>

每个新的主要版本都包括对查询优化程序的增强，旨在提高性能。但是，您的工作负载可能包括导致新版本中计划性能较差的查询。正因如此，我们建议您在生产环境中进行升级之前，先测试和审查性能。您可以使用查询计划管理 (QPM) 扩展来管理跨版本的查询计划稳定性，详情请参阅 [确保主要版本升级后的计划稳定性](AuroraPostgreSQL.Optimize.BestPractice.md#AuroraPostgreSQL.Optimize.BestPractice.MajorVersionUpgrade)。

在将生产 Aurora PostgreSQL 数据库集群升级到新的主要版本之前，我们强烈建议您测试升级，以验证所有应用程序是否正常工作：

1. 准备好一个版本兼容的参数组。

   如果您使用的是自定义数据库实例或数据库集群参数组，您可以从两个选项中进行选择：

   1. 为新的数据库引擎版本指定默认数据库实例和/或数据库集群参数组。

   1. 为新的数据库引擎版本创建您自己的自定义参数组。

1. 检查是否存在无效数据库，并删除所有存在的无效数据库。

   `pg_database` 目录中的 `datconnlimit` 列包含值 `-2`，用于将在 `DROP DATABASE` 操作期间中断的任何数据库标记为无效。使用以下查询来检查是否存在无效的数据库。

   ```
   SELECT
       datname
   FROM
       pg_database
   WHERE
       datconnlimit = - 2;
   ```

   如果查询返回数据库名称，则这些数据库无效。使用 `DROP DATABASE invalid_db_name` 语句删除无效的数据库。可以使用以下动态语句来删除所有无效数据库。

   ```
   SELECT
       'DROP DATABASE ' || quote_ident(datname) || ';'
   FROM
       pg_database
   WHERE
       datconnlimit = -2 \gexec
   ```

1. 检查是否有不支持的使用方式：
   + 在尝试升级前，提交或回滚所有打开的已准备事务。您可以使用以下查询确认您的实例上是否没有打开的已准备事务。

     ```
     SELECT count(*) FROM pg_catalog.pg_prepared_xacts;
     ```
   + 在尝试升级前取消使用所有 *reg\$1* 数据类型。除了 `regtype` 和 `regclass` 以外，您不能升级 *reg\$1* 数据类型。pg\$1upgrade 实用工具（Amazon Aurora 用来执行升级）不能保留这个数据类型。要了解有关此实用程序的更多信息，请参阅 PostgreSQL 文档中的 [pg\$1upgrade](https://www.postgresql.org/docs/current/pgupgrade.html)。

     要验证是否没有使用不支持的 *reg\$1* 数据类型，请对每个数据库使用以下查询。

     ```
     SELECT count(*) FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_attribute a 
       WHERE c.oid = a.attrelid 
           AND NOT a.attisdropped 
           AND a.atttypid IN ('pg_catalog.regproc'::pg_catalog.regtype, 
                              'pg_catalog.regprocedure'::pg_catalog.regtype, 
                              'pg_catalog.regoper'::pg_catalog.regtype, 
                              'pg_catalog.regoperator'::pg_catalog.regtype, 
                              'pg_catalog.regconfig'::pg_catalog.regtype, 
                              'pg_catalog.regdictionary'::pg_catalog.regtype) 
           AND c.relnamespace = n.oid 
           AND n.nspname NOT IN ('pg_catalog', 'information_schema');
     ```
   + 如果对已安装 `pgRouting` 扩展的 Aurora PostgreSQL 10.18 版本或更高版本进行升级，请删除此扩展，然后再升级到 12.4 或更高版本。

     如果您正在升级安装了扩展 `pg_repack` 版本 1.4.3 的 Aurora PostgreSQL 10.x 版本，请在升级到任何更高版本之前删除该扩展。

1. 检查 template1 和 template0 数据库。

   要成功升级，template1 和 template 0 数据库必须存在且应作为模板列出。要对此进行检查，请使用以下命令：

   ```
   SELECT datname, datistemplate FROM pg_database; 
                           
   datname    | datistemplate
   -----------+---------------
   template0  | t
   rdsadmin   | f
   template1  | t
   postgres   | f
   ```

   在命令输出中，template1 和 template0 数据库的 `datistemplate` 值应为 `t`。

1. 删除逻辑复制槽。

   如果 Aurora PostgreSQL 数据库集群正在使用任何逻辑复制槽，则升级过程无法继续。逻辑复制槽通常用于短期数据迁移任务，例如使用 AWS DMS 迁移数据或将表从数据库复制到数据湖、BI 工具或其他目标。升级之前，请确保您知道存在的任何逻辑复制槽的用途，并确认可以删除它们。您可以使用以下查询来检查逻辑复制槽：

   ```
   SELECT * FROM pg_replication_slots;
   ```

   如果逻辑复制槽仍在使用中，则不应将其删除，但也无法继续升级。但是，如果不需要逻辑复制槽，则可以使用以下 SQL 将其删除：

   ```
   SELECT pg_drop_replication_slot(slot_name);
   ```

   使用 `pglogical` 扩展的逻辑复制方案还需要从发布者节点上删除插槽，才能在该节点上成功升级主要版本。但是，可以在升级后从订阅者节点重新启动复制过程。有关更多信息，请参阅 [在主要升级后重新建立逻辑复制](Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.md)。

1. 执行备份。

   在升级期间，升级进程创建数据库集群的数据库集群快照。如果您还希望在升级进程之前执行手动备份，有关更多信息，请参阅[创建数据库集群快照](USER_CreateSnapshotCluster.md)。

1. 在执行主要版本升级之前，将某些扩展升级到最新的可用版本。要更新的扩展包括以下各项：
   + `pgRouting`
   + `postgis_raster`
   + `postgis_tiger_geocoder`
   + `postgis_topology`
   + `address_standardizer`
   + `address_standardizer_data_us`

   对当前安装的每个扩展运行以下命令。

   ```
   ALTER EXTENSION PostgreSQL-extension UPDATE TO 'new-version';
   ```

   有关更多信息，请参阅 [升级 PostgreSQL 扩展](USER_UpgradeDBInstance.Upgrading.ExtensionUpgrades.md)。要了解有关升级 PostGIS 的更多信息，请参阅[步骤 6：升级 PostGIS 扩展](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)。

1. 如果要升级到版本 11.x，请在执行主要版本升级之前删除它不支持的扩展。要删除的扩展包括：
   + `chkpass`
   + `tsearch2` 

1. 删除 `unknown` 数据类型，具体取决于您的目标版本。

   PostgreSQL 版本 10 不支持 `unknown` 数据类型。如果版本 9.6 数据库使用 `unknown` 数据类型，升级到版本 10 将显示错误消息，如下所示。

   ```
   Database instance is in a state that cannot be upgraded: PreUpgrade checks failed: 
   The instance could not be upgraded because the 'unknown' data type is used in user tables. 
   Please remove all usages of the 'unknown' data type and try again."
   ```

   要在数据库中查找 `unknown` 数据类型，以便删除上述列或将其更改为支持的数据类型，请为每个数据库使用以下 SQL 代码。

   ```
   SELECT n.nspname, c.relname, a.attname
       FROM pg_catalog.pg_class c,
       pg_catalog.pg_namespace n,
       pg_catalog.pg_attribute a
       WHERE c.oid = a.attrelid AND NOT a.attisdropped AND
       a.atttypid = 'pg_catalog.unknown'::pg_catalog.regtype AND
       c.relkind IN ('r','m','c') AND
       c.relnamespace = n.oid AND
       n.nspname !~ '^pg_temp_' AND
       n.nspname !~ '^pg_toast_temp_' AND n.nspname NOT IN ('pg_catalog', 'information_schema');
   ```

1. 执行空运行升级。

   我们强烈建议您先使用生产数据库的副本测试主要版本升级，然后再对生产数据库真正执行升级。您可以监控重复测试实例上的执行计划，以了解任何可能的执行计划回归，并评估其性能。要创建副本测试实例，您可以从最近的快照还原数据库，或者克隆数据库。有关更多信息，请参阅 [从快照还原](aurora-restore-snapshot.md#aurora-restore-snapshot.Restoring) 或 [克隆 Amazon Aurora 数据库集群卷](Aurora.Managing.Clone.md)。

   有关更多信息，请参阅“[将 Aurora PostgreSQL 引擎升级到新的主要版本](#USER_UpgradeDBInstance.Upgrading.Manual)”。

1. 升级您的生产实例。

   当试验性运行主要版本升级获得成功时，您应该可以放心地升级您的生产数据库。有关更多信息，请参阅 [将 Aurora PostgreSQL 引擎升级到新的主要版本](#USER_UpgradeDBInstance.Upgrading.Manual)。

   
**注意**  
在升级过程中，Aurora PostgreSQL 会制作数据库集群快照。在此过程中，您无法执行集群的时间点还原。之后，您可以执行时间点还原，以将实例还原到实例自动快照完成之后、升级操作开始之前的时间。但是，您不能通过执行时间点还原来还原到以前的次要版本。

   有关进行中的升级的信息，您可以使用 Amazon RDS 来查看 pg\$1upgrade 实用工具生成的两个日志。它们是 `pg_upgrade_internal.log` 和 `pg_upgrade_server.log`。Amazon Aurora 会在这些日志的文件名中附加时间戳。您可以像查看其他任何日志一样查看这些日志。有关更多信息，请参阅“[监控 Amazon Aurora 日志文件](USER_LogAccess.md)”。

1. 升级 PostgreSQL 扩展。PostgreSQL 升级过程不会升级任何 PostgreSQL 扩展。有关更多信息，请参阅 [升级 PostgreSQL 扩展](USER_UpgradeDBInstance.Upgrading.ExtensionUpgrades.md)。

## 升级后建议
<a name="USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Upgrade.postupgrade"></a>

完成主要版本升级后，我们建议您执行以下操作：
+ 运行 `ANALYZE` 操作以刷新 `pg_statistic` 表。您应该为所有 PostgreSQL 数据库实例上的每个数据库执行此操作。在主要版本升级期间不会传输优化程序统计数据，因此您需要重新生成所有统计数据，避免出现性能问题。运行不带任何参数的命令，为当前数据库中的所有常规表生成统计数据，如下所示：

  ```
  ANALYZE VERBOSE;
  ```

  `VERBOSE` 标记为可选项，可用于显示进度。有关更多信息，请参阅 PostgreSQL 文档中的 [ANALYZE](https://www.postgresql.org/docs/10/sql-analyze.html)。

  在分析特定表而不是使用 ANALYZE VERBOSE 时，请对每个表运行 ANALYZE 命令，如下所示：

  ```
  ANALYZE table_name;
  ```

  对于分区表，请始终分析父表。此过程：
  + 自动对所有分区中的行进行采样
  + 以递归方式更新每个分区的统计数据
  + 在父级维护基本的规划统计数据

  尽管父表不存储任何实际数据，但分析父表对于查询优化至关重要。仅对各个分区运行 ANALYZE 会导致查询性能不佳，因为优化器不具备进行高效跨分区规划所需的全面统计数据。
**注意**  
升级后在系统上运行 ANALYZE，避免出现性能问题。
+ 如果您升级到 PostgreSQL 版本 10，请在您拥有的任何哈希索引上运行 `REINDEX`。哈希索引在版本 10 中已更改，必须重新构建。要查找无效的哈希索引，请针对包含哈希索引的每个数据库运行以下 SQL。

  ```
  SELECT idx.indrelid::regclass AS table_name, 
     idx.indexrelid::regclass AS index_name 
  FROM pg_catalog.pg_index idx
     JOIN pg_catalog.pg_class cls ON cls.oid = idx.indexrelid 
     JOIN pg_catalog.pg_am am ON am.oid = cls.relam 
  WHERE am.amname = 'hash' 
  AND NOT idx.indisvalid;
  ```
+ 建议您在升级的数据库上使用类似的工作负载测试应用程序，以验证是否一切正常。验证升级之后，您可以删除此测试实例。

## 将 Aurora PostgreSQL 引擎升级到新的主要版本
<a name="USER_UpgradeDBInstance.Upgrading.Manual"></a>

当您启动升级到新的主要版本的过程时，Aurora PostgreSQL 会在对集群进行任何更改之前拍摄 Aurora DB 集群的快照。此快照仅针对主要版本升级（而不是次要版本升级）而创建。升级过程完成后，您可以在 RDS 控制台的 **Snapshots**（快照）下列出的手动快照中找到此快照。快照名称包括 `preupgrade`（作为其前缀）、Aurora PostgreSQL 数据库集群的名称、源版本、目标版本以及日期和时间戳，如以下示例所示。

```
preupgrade-docs-lab-apg-global-db-12-8-to-13-6-2022-05-19-00-19
```

升级完成后，如有必要，您可以使用 Aurora 创建并存储在手动快照列表中的快照，将数据库集群还原到其以前的版本。

**提示**  
一般来说，快照提供了许多将 Aurora 数据库集群还原到不同时间点的方法。要了解更多信息，请参阅 [从数据库集群快照还原](aurora-restore-snapshot.md) 和 [将数据库集群还原到指定时间](aurora-pitr.md)。但是，Aurora PostgreSQL 不支持使用快照还原到以前的次要版本。

在主要版本升级过程中，Aurora 将分配卷并克隆源 Aurora PostgreSQL 数据库集群。如果升级由于任何原因而失败，Aurora PostgreSQL 将使用克隆回滚升级。当分配的源卷克隆超过 15 个之后，后续克隆将成为完整副本并且需要更长的时间。这可能导致升级过程也要花费更长的时间。如果 Aurora PostgreSQL 回滚升级，请注意以下事项：
+ 您可能会看到在升级期间分配的原始卷和克隆卷的账单条目和指标。在集群备份保留时段超过升级时间之后，Aurora PostgreSQL 会清理额外的卷。
+ 此集群中的下一个跨区域快照副本将为完整副本，而不是增量副本。

为了安全地升级构成集群的数据库实例，Aurora PostgreSQL 使用 pg\$1upgrade 实用程序。写入器升级完成后，每个读取器实例在升级到新的主要版本时都会出现短暂中断。要了解有关此 PostgreSQL 实用程序的更多信息，请参阅 PostgreSQL 文档中的 [pg\$1upgrade](https://www.postgresql.org/docs/current/pgupgrade.html)。

您可以使用以下方法将 Aurora PostgreSQL 数据库集群升级到新版本：AWS 管理控制台、AWS CLI 或 RDS API。

### 控制台
<a name="USER_UpgradeDBInstance.Upgrading.Manual.Console"></a>

**升级数据库集群的引擎版本**

1. 登录AWS 管理控制台并通过以下网址打开 Amazon RDS 控制台：[https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)。

1. 在导航窗格中，选择 **Databases (数据库)**，然后选择要升级的数据库集群。

1. 选择**修改**。此时会显示**修改数据库集群**页面。

1. 对于**数据库引擎版本**，选择新版本。

1. 选择**继续**，查看修改摘要。

1. 要立即应用更改，请选择**立即应用**。选择此选项在某些情况下可能导致中断。有关更多信息，请参阅“[修改 Amazon Aurora 数据库集群](Aurora.Modifying.md)”。

1. 在确认页面上，检查您的更改。如果更改正确无误，请选择**修改集群**以保存更改。

   也可以选择 **Back** 编辑您的更改，或选择 **Cancel** 取消更改。

### AWS CLI
<a name="USER_UpgradeDBInstance.Upgrading.Manual.CLI"></a>

要升级数据库集群的引擎版本，请使用 AWS CLI 命令 [modify-db-cluster](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-cluster.html)。指定以下参数：
+ `--db-cluster-identifier` – 数据库集群的名称。
+ `--engine-version` – 数据库引擎要升级到的版本号。有关有效的引擎版本的信息，请使用 AWS CLI [describe-db-engine-versions](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html) 命令。
+ `--allow-major-version-upgrade` – 当 `--engine-version` 参数是不同于数据库集群当前主要版本的主要版本时，这是必需的标志。
+ `--no-apply-immediately` – 在下一维护时段内应用更改。要立即应用更改，请使用 `--apply-immediately`。

**Example**  
对于 Linux、macOS 或 Unix：  

```
1. aws rds modify-db-cluster \
2.     --db-cluster-identifier mydbcluster \
3.     --engine-version new_version \
4.     --allow-major-version-upgrade \
5.     --no-apply-immediately
```
对于：Windows  

```
1. aws rds modify-db-cluster ^
2.     --db-cluster-identifier mydbcluster ^
3.     --engine-version new_version ^
4.     --allow-major-version-upgrade ^
5.     --no-apply-immediately
```

### RDS API
<a name="USER_UpgradeDBInstance.Upgrading.Manual.API"></a>

要升级数据库集群的引擎版本，请使用 [ModifyDBCluster](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBCluster.html) 操作。指定以下参数：
+ `DBClusterIdentifier` – 数据库集群的名称，例如 *`mydbcluster`*。
+ `EngineVersion` – 数据库引擎要升级到的版本号。有关有效的引擎版本的信息，请使用 [DescribeDBEngineVersions](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBEngineVersions.html) 操作。
+ `AllowMajorVersionUpgrade` – 当 `EngineVersion` 参数是不同于数据库集群当前主要版本的主要版本时，这是必需的标志。
+ `ApplyImmediately` – 是立即应用更改还是在下一个维护时段内应用更改。要立即应用更改，请将该值设置为 `true`。要在下一个维护时段内应用更改，请将该值设置为 `false`。

### 全局数据库的主要版本升级
<a name="USER_UpgradeDBInstance.PostgreSQL.GlobalDB"></a>

对于 Aurora 全局数据库集群，升级过程会同时升级构成 Aurora 全局数据库的所有数据库集群。这样做是为了确保每个数据库集群都运行相同的 Aurora PostgreSQL 版本。它还可确保对系统表、数据文件格式等所做的任何更改都会自动复制到所有辅助集群。

要将全局数据库集群升级到 Aurora PostgreSQL 的新主要版本，我们建议您在升级的版本上测试应用程序，如[测试将生产数据库集群升级到新的主要版本](#USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Upgrade.preliminary)中所述。请确保在升级之前为 Aurora 全局数据库中的每个 AWS 区域准备好数据库集群参数组和数据库参数组设置，详见[测试将生产数据库集群升级到新的主要版本](#USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Upgrade.preliminary)中的[step 1.](#step-1)。

如果 Aurora PostgreSQL 全局数据库集群为其 `rds.global_db_rpo` 参数设置了恢复点目标 (RPO)，请确保在升级之前重置此参数。如果开启了 RPO，主要版本升级过程将不起作用。默认情况下，该参数处于停用状态。有关 Aurora PostgreSQL 全局数据库和 RPO 的更多信息，请参阅[管理基于 Aurora PostgreSQL 的全局数据库的 RPO](aurora-global-database-disaster-recovery.md#aurora-global-database-manage-recovery)。

如果您验证应用程序可以在新版本的试用部署时按预期运行，则可以启动升级过程。为此，请参阅 [将 Aurora PostgreSQL 引擎升级到新的主要版本](#USER_UpgradeDBInstance.Upgrading.Manual)。请确保从 RDS 控制台的 **Databases**（数据库）列表中选择顶级项，即 **Global database**（全局数据库），如下图所示。

![\[控制台图像，其中显示 Aurora 全局数据库、Aurora Serverless 数据库集群和另一个 Aurora PostgreSQL 数据库集群\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/images/aurora-global-database-plus-other.png)


与任何修改一样，当出现提示时，您可以确认您希望继续执行该过程。

![\[控制台图像，其中显示用于确认 Aurora PostgreSQL 数据库集群升级过程的提示\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/images/aurora-global-db-apg-upgrade-2.png)


您可以使用 AWS CLI 或 RDS API 启动升级过程，而不是使用控制台。与控制台一样，您在 Aurora 全局数据库集群而不是其任何组件上运行，如下所示：
+ 使用 AWS CLI 命令 [modify-global-cluster](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-global-cluster.html)，通过使用 AWS CLI 启动 Aurora 全局数据库的升级。
+ 使用 [ModifyGlobalCluster](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyGlobalCluster.html) API 启动升级。