如何解决 Amazon RDS for PostgreSQL 和 Aurora for PostgreSQL 中的主要版本升级问题?

上次更新日期:2022 年 11 月 21 日

我的 Amazon Relational Database Service(Amazon RDS)for PostgreSQL 或兼容 Amazon Aurora PostgreSQL 的版本的引擎版本升级停滞或失败。

简短描述

当 Amazon RDS 支持新版本的数据库引擎时,您可以将数据库实例升级到新版本。您可以对数据库实例执行次要版本等级或主要版本升级。

次要版本升级用于修补安全漏洞和修复错误。这些升级通常不会添加任何新功能,也不会更改内部存储格式。它们始终与同一主要版本的早期和更高版本的次要版本兼容。但是,主要版本升级包含非向后兼容现有应用程序的数据库更改。这些升级可能会更改系统表、数据文件和数据存储的内部格式。Amazon RDS 使用 PostgreSQL 实用程序 pg_upgrade 执行主要版本升级。

在 PostgreSQL 实例的主要版本升级期间,Amazon RDS 会运行预检查程序。此过程可识别任何可能导致升级失败的问题。预检查程序检查所有数据库中是否存在潜在的不兼容条件。如果 Amazon RDS 在预检查过程中发现问题,则会为失败的预检查创建日志事件。有关所有数据库的预检查过程的更多信息,请查看 pg_upgrade_precheck.log 升级日志。Amazon RDS 会将时间戳附加到文件名。RDS 事件也可能提供升级失败的原因。但是,对于特定于引擎的问题,必须检查数据库日志文件。

有关详细信息,请参阅针对 RDS for PostgreSQL 查看和列出数据库日志文件。或者,请参阅针对 Aurora for PostgreSQL 查看和列出数据库日志文件

在主要版本升级期间,RDS 将完成以下步骤:

  1. 在升级前创建实例的快照。仅在将数据库实例的备份保留期设置为大于 0 的数字时,才会发生这种情况。
  2. 关闭实例。
  3. 使用 pg_upgrade 实用工具在实例上运行升级作业。
  4. 在升级后创建实例的快照。

解决方法

尽管 Amazon RDS 管理这些升级,但在版本升级期间您可能会遇到以下问题:

  • 升级需要更长时间。
  • 升级失败。

升级需要很长时间

待处理的维护活动:任何待处理的维护活动都会在引擎版本升级时自动应用。这可能包括在您的 RDS 实例上应用操作系统补丁。在这种情况下,首先应用操作系统补丁,然后升级引擎版本。因此,执行操作系统维护活动会增加完成升级所花费的时间。

此外,如果您的 RDS 实例处于多可用区部署中,则操作系统维护会引发失效转移。在多可用区中设置实例时,通常会在辅助实例上创建实例的备份。如果发生失效转移,则会在升级后于新的辅助实例上创建备份。新辅助实例上的此备份可能不是最新的备份。因此,可能会触发完全备份,而不是增量备份。创建完全备份可能需要很长时间,尤其是在数据库规模非常大的情况下。

为避免此问题,请在 RDS 控制台的待处理维护部分中查找待处理的维护活动。有关 Aurora for PostgreSQL,请参阅查看待处理维护

或者,在您的实例上使用 AWS 命令行界面(AWS CLI)命令 describe-pending-maintenance-actions

aws rds describe-pending-maintenance-actions --resource-identifier example-arn

注意:在执行数据库引擎版本升级之前,请完成这些维护活动。

升级前未创建快照:最佳实践是在执行升级之前针对 RDS 或 Aurora for PostgreSQL 集群快照创建快照。如果已经为实例启用备份,则会在升级过程中自动创建快照。在升级之前创建快照可以缩短升级过程完成所需的时间。这是因为在这种情况下,升级过程中只会创建增量备份。

RDS for PostgreSQL 只读副本升级:对主数据库实例执行主要版本升级时,同一区域中的所有只读副本会自动升级。升级工作流程启动后,只读副本将等待主数据库实例上的 pg_upgrade 成功完成。然后,主实例升级将等待只读副本升级完成。在所有升级完成之前,您会遇到中断。如果升级的停机时间有限,则可以升级或删除副本实例。然后,在升级完成后重新创建只读副本

为安全地升级构成集群的数据库实例,Aurora for PostgreSQL 会使用 pg_upgrade 实用程序。写入器升级完成后,每个读取器实例在升级到新的主要版本时都会经历短暂的中断。

长时间运行的事务或升级前的高工作负载:长时间运行的事务或升级前的高工作负载可能会增加关闭数据库所需的时间,并延长升级时间。

运行以下查询以识别长时间运行的事务:

SQL>SELECT pid, datname, application_name, state, 
age(query_start, clock_timestamp()), usename, query 
FROM pg_stat_activity 
WHERE query NOT ILIKE '%pg_stat_activity%' AND 
usename!='rdsadmin' 
ORDER BY query_start desc;

计算容量不足:pg_upgrade 实用程序可能是计算密集型的。因此,最佳实践是在升级生产数据库之前执行空运行升级。您可以还原生产实例的快照,并使用与生产数据库相同的实例类执行空运行。

升级失败

不支持的数据库实例类:如果数据库实例的实例类与您要升级到的 PostgreSQL 版本不兼容,则升级可能会失败。请务必检查实例类与引擎版本的兼容性。有关更多信息,请查看支持的 RDS for PostgreSQL 的数据库实例类数据库引擎。或者,查看支持的 Aurora for PostgreSQL 的数据库实例类数据库引擎

开放的准备事务:在数据库中开放的准备事务可能会导致升级失败。在开始升级之前,请务必提交或回滚所有开放的准备事务。

运行以下查询来检查您的实例上是否有开放的准备事务:

SELECT count(*) FROM pg_catalog.pg_prepared_xacts;

在这种情况下,pg_upgrade.log 文件中的错误类似于以下内容:

------------------------------------------------------------------------
Upgrade could not be run on Wed Apr 4 18:30:52 2018
-------------------------------------------------------------------------
The instance could not be upgraded from 9.6.11 to 10.6 for the following reasons.
Please take appropriate action on databases that have usage incompatible with 
the requested major engine version upgrade and try the upgrade again.

*There are uncommitted prepared transactions. Please commit or rollback 
all prepared transactions.*

不支持的数据类型:如果尝试使用不受支持的数据类型升级数据库,升级将失败并出现错误,例如:

  • regcollation
  • regconf
  • regdictionary
  • regnamespace
  • regoper
  • regoperator
  • regproc
  • regprocedure

注意:支持数据类型 regclass、regrole 和 regtype。

PostgreSQL 升级实用程序 pg_upgrade 不支持使用引用 reg* OID 的系统数据类型升级包含表列的数据库。在尝试升级之前,请删除 regclass、regrole 和 regtype 之外的所有 reg* 数据类型使用情况。

运行以下查询以验证不支持的 reg* 数据类型的使用情况:

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');

逻辑复制槽:如果您的实例有任何逻辑复制槽,则无法进行升级。逻辑复制槽通常用于 AWS Database Migration Service(AMS DMS)迁移。它们还用于将表从数据库复制到数据湖、商业智能工具和其他目标。升级之前,请确保您知道正在使用的逻辑复制槽的用途,并确认它们可以删除。

如果逻辑复制槽仍在使用,则不能将其删除。在此情况下,您无法继续升级。

pg_upgrade 日志文件中的相关错误类似于以下内容:

"The instance could not be upgraded because one or more databases have logical replication slots. Please drop all logical replication slots and try again."

如果不需要逻辑复制槽,请运行以下查询将其删除:

SELECT * FROM pg_replication_slots;
SELECT pg_drop_replication_slot(slot_name);

存储问题:当 pg_upgrade 脚本运行时,实例可能会耗尽空间。这会导致脚本失败,并且您会看到类似于以下内容的错误消息:

pg_restore: [archiver (db)] Error while PROCESSING TOC: 
pg_restore: [archiver (db)] could not execute query: ERROR: could not create file "base/12345/12345678": No space keyword" left  on device

要解决此问题,请确保实例有足够的可用存储空间,然后再开始升级。

未知数据类型:PostgreSQL 版本 10 及更高版本不支持未知数据类型。如果 PostgreSQL 9.6 版数据库使用未知数据类型,则将 PostgreSQL 升级到版本 10 时会显示类似于以下内容的错误消息:

"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."

这是 PostgreSQL 的限制,RDS 自动化不会修改使用未知数据类型的列。在升级之前,您可能需要手动修改这些列。

运行以下查询,在数据库中查找带有未知数据类型的列:

SELECT DISTINCT data_type FROM information_schema.columns WHERE data_type ILIKE 'unknown';

标识列后,您可以删除这些列或将其修改为支持的数据类型。

只读副本升级失败(仅 RDS for PostgreSQL):PostgreSQL 实例具有只读副本,则只读副本升级失败可能会导致您的主实例升级卡滞。只读副本升级失败也可能导致主实例升级失败。失败的只读副本将置于 incompatible-restore 状态,并在数据库实例上停止复制。

只读副本升级可能由于以下原因之一而失败:

  • 即使在等待时间过后,只读副本也无法赶上主数据库实例。
  • 只读副本处于终止或不兼容的生命周期状态,例如 storage-full 或 incompatible-restore。
  • 主数据库实例升级开始时,只读副本上正在运行单独的次要版本升级。
  • 只读副本使用了不兼容的参数。
  • 只读副本无法与主数据库实例通信以同步数据文件夹。

要解决此问题,请删除只读副本。然后,在主实例升级后,根据升级后的主实例重新创建新的只读副本。

主用户名不正确:如果主用户名以“pg_”开头,则升级失败,并且您会看到以下错误消息:

PreUpgrade checks failed: The instance could not be upgraded because one or more role names start with 'pg_'. Please rename  all roles with names that start with 'pg_' and try again

要解决此问题,请创建另一个具有 rds_superuser 角色的用户。您可以联系 AWS Support,将此用户更新为新的主用户。

不兼容的参数错误:如果将与内存相关的参数(如 shared_bufferwork_memory)设置为更高的值,则会出现此错误。这可能会导致升级脚本失败。要解决此问题,请减少这些参数的值,然后再次尝试运行升级。

升级前未更新扩展:主要版本升级不会升级任何 PostgreSQL 扩展。如果您在执行主要版本升级之前没有更新扩展,则会在 pg_upgrade.log 文件中看到以下错误:

The Logs indicates that the RDS instance ''xxxx'' has older version of PostGIS extension or its dependent extensions (address_standardizer,address_standardizer_data_us, postgis_tiger_geocoder, postgis_topology, postgis_raster) installed as against the current version required for the upgrade.

此错误消息表示 PostGIS 扩展存在问题。

请运行以下查询以检查 PostGIS 及其相关扩展的默认版本和已安装版本:

SELECT name, default_version, installed_version
FROM pg_available_extensions WHERE installed_version IS NOT NULL AND
name LIKE 'postgis%' OR name LIKE 'address%';

如果 installed_version 的值小于 default_version 的值,则必须将 PostGIS 更新到默认版本。为此,请运行此查询:

ALTER EXTENSION extension_name UPDATE TO 'default_version_number';

有关更多信息,请参阅升级 PostgreSQL 扩展(针对 RDS for PostgreSQL)或升级 PostgreSQL 扩展(针对 Aurora PostgreSQL)。

由于目标版本的系统目录发生变化而导致视图问题:某些视图中的列在不同的 PostgreSQL 版本中有所不同。

例如,您可能会看到以下错误消息:

PreUpgrade checks failed: The instance could not be upgraded because one or more databases have views or materialized views which depend on 'pg_stat_activity'. Please drop them and try again.

将数据库从版本 9.5 升级到 9.6 时会出现此错误。此错误是由 pg_stat_activity 视图引起的,因为在 9.6 版中,waiting 列替换为 wait_event_typewait_event 列。

pg_restore: from TOC entry xxx; xxx xxxx VIEW sys_user_constraints art 
pg_restore: error: could not execute query: ERROR: column c.consrc does not exist LINE 18: "c"."consrc" AS "search_condition", ^ HINT: Perhaps you meant to reference the column "c.conkey" or the column "c.conbin".

之所以出现此错误,是因为目录 pg_constraint 的结构在 PostgreSQL 版本 12 中已更改。

可以通过删除基于目标版本系统目录的视图来解决这些问题。

注意:删除这些视图时请务必小心。请务必咨询您的 DBA。

其他注意事项

  • pg_upgrade 实用程序会生成两个日志:pg_upgrade_internal.logpg_upgrade_server.log。Amazon RDS 会将时间戳附加到这些日志的文件名。查看这些日志以获取有关升级期间遇到的问题和错误的更多信息。有关更多信息,请参阅监控 Amazon RDS 日志文件(针对 RDS for PostgreSQL)或监控 Amazon Aurora 日志文件(针对 Aurora for PostgreSQL)。
  • 升级完成后,通过对所有用户数据库运行 ANALYZE 来升级 pg_statistics 表。主要升级不会将 pg_statistics 表的内容移至新版本。跳过此步骤可能会导致查询运行缓慢。
  • 如果升级到 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;

这篇文章对您有帮助吗?


您是否需要账单或技术支持?