如何对 Amazon RDS for PostgreSQL 或 Aurora PostgreSQL 兼容版中的主要版本升级问题进行故障排除?
我的 Amazon Relational Database Service (Amazon RDS) for PostgreSQL 或 Amazon Aurora PostgreSQL 兼容版的引擎版本升级卡住或者失败了。
简短描述
主要版本升级包含数据库更改,这些更改与现有应用程序不向后兼容。这些升级可能会更改系统表、数据文件和数据存储的内部格式。Amazon RDS 使用 pg_upgrade 来执行主要版本升级。有关更多信息,请参阅 PostgreSQL 网站上的 pg_upgrade。
在主要版本升级期间,Amazon RDS 会运行预检查程序,以识别可能导致升级失败的问题。它会检查所有数据库中是否存在潜在的不兼容情况。如果 Amazon RDS 在预检查过程中发现了问题,则会为失败的预检查创建日志事件。日志事件中会包括文件名、时间戳以及升级失败的原因。有关所有数据库预检查过程的信息,请查看 pg_upgrade_precheck.log 日志。对于特定于引擎的问题,您必须检查 Amazon RDS for PostgreSQL 或 Aurora PostgreSQL 的数据库日志文件。
解决方法
执行主要版本升级的 pg_upgrade 实用程序会生成 pg_upgrade_internal.log 日志和 pg_upgrade_server.log 日志。Amazon RDS 会在日志的文件名中附加时间戳。查看这些日志,以获取有关升级期间遇到的问题和错误的详细信息。有关详细信息,请参阅监控 Amazon RDS 日志文件或监控 Amazon Aurora 日志文件。
长时间运行的升级
检查是否存在待处理的维护活动
如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
Amazon RDS 会自动通过引擎版本升级来应用待处理的维护活动,例如在 Amazon RDS 实例上安装操作系统 (OS) 补丁。Amazon RDS 首先应用待处理的活动,然后升级引擎版本。如果 Amazon RDS 必须执行操作系统维护活动,则升级需要更长的时间。
如果您的 Amazon RDS 实例处于多可用区部署中,则操作系统维护会导致失效转移。当您在多可用区环境中设置实例时,Amazon RDS 通常会在辅助实例上创建实例的备份。在失效转移中,Amazon RDS 会在升级后在新的辅助实例上创建备份。这个位于新辅助实例上的备份可能不是最新的备份,因此 Amazon RDS 完成的是完整备份,而不是增量备份。完整备份可能需要很长时间,尤其是在数据库很大的情况下。
为避免此问题,请搜索您的 RDS 数据库实例或 Aurora 数据库实例的待处理维护活动。或者,在您的实例上运行以下 describe-pending-maintenance-actions AWS CLI 命令:
aws rds describe-pending-maintenance-actions --resource-identifier example-arn
**注意:**请将 example-arn 替换为您的数据库实例的 ARN。
在执行数据库引擎版本升级之前,完成待处理的维护活动。
在升级之前创建快照
在升级版本之前,最佳做法是创建 RDS 数据库实例的快照或 Aurora 数据库集群的快照。如果您已经为实例开启了备份,则 Amazon RDS 会在升级过程中自动创建快照。快照可以缩短升级过程时间,因为 Amazon RDS 只需要在升级过程中创建增量备份。
等待只读副本升级
当您对主数据库实例执行主要版本升级时,Amazon RDS 会自动升级同一 AWS 区域中的所有只读副本。升级工作流启动后,只读副本会等待主数据库实例上的 pg_upgrade 成功完成。然后,主数据库实例升级会等待只读副本升级完成。在所有升级完成之前,数据库实例将处于关闭状态。如果升级的停机时间很短,请升级或删除您的副本实例,然后在升级完成后重新创建只读副本。
对于 Aurora 数据库集群,pg_upgrade 会先升级写入器实例。然后,当 pg_upgrade 将每个读取器数据库实例升级到新的主要版本时,这些实例将关闭。
**注意:**如果您升级 Aurora 全局数据库,则还有其他要求和流程。
在升级之前解决长时间运行的事务或高工作负载的问题
长时间运行的事务或高工作负载会增加 Amazon RDS 关闭数据库和升级数据库引擎所需的时间。
要识别长时间运行的事务,请运行以下查询:
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_cancel_backend 或 pg_terminate_backend 结束该事务。有关 pg_cancel_backend 和 pg_terminate_backend 的详细信息,请参阅 PostgreSQL 网站上的 Server signaling functions(服务器信号函数)。
确保您有足够的计算容量
pg_upgrade 实用程序可能会占用大量计算资源。要检查您是否有足够的计算容量或内存容量,最佳做法是在升级生产数据库之前执行测试升级。测试升级还会检查您是否可能遇到预检查或升级错误。您可以恢复生产实例的快照,并使用与生产数据库实例类相同的实例类进行测试。
升级失败
检查是否存在不支持的数据库实例类
如果您的数据库实例的实例类与您要升级到的 PostgreSQL 版本不兼容,则升级将失败。检查引擎版本与 Amazon RDS 或 Amazon Aurora 的实例类的兼容性。
检查是否存在未结的已准备事务
如果数据库上存在未结的已准备事务,则升级将失败。您会在 pg_upgrade.log 文件中收到“There are uncommitted prepared transactions”错误。在开始升级之前,请提交或回滚所有未结的已准备事务。
要检查您的实例上是否存在未结的已准备事务,请运行以下查询:
SELECT count(*) FROM pg_catalog.pg_prepared_xacts;
使用受支持的数据类型
您只能升级 regclass、regrole 和 regtype 数据类型的版本。pg_upgrade 实用程序无法升级包含使用 reg* 对象标识符 (OID) 引用类型的表列的数据库。如果您使用 regcollation、regconfig、regdictionary、regnamespace、regoper、regoperator、regproc 或 regprocedure 数据类型,则升级将失败。
要解决此问题,请在升级数据引擎之前移除所有 reg* 数据类型(regclass、regrole 和 regtype 除外)的使用。要检查表中是否存在不支持的 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');
检查是否存在逻辑复制槽
如果您的实例存在逻辑复制槽,则您无法升级实例,且会在 pg_upgrade.log 文件中收到以下错误消息:
“The instance could not be upgraded because one or more databases have logical replication slots.Please drop all logical replication slots and try again.”
逻辑复制槽通常用于 AWS Database Migration Service (AMS DMS) 迁移。它们还用于将表从数据库复制到数据湖、商业智能工具和其他目标。确保您了解当前使用的逻辑复制槽的用途,以确定是否可以将其删除。如果逻辑复制槽正在使用中,请勿将其删除。必须等待版本升级完成,然后才能删除逻辑复制槽。
如果您不需要逻辑复制槽,请运行以下命令将其删除:
SELECT * FROM pg_replication_slots;
SELECT pg_drop_replication_slot(slot_name);
**注意:**请将 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 数据库使用未知的数据类型,则您在升级到版本 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.”
要解决此问题,请手动删除使用 unknown 数据类型的列或将其修改为支持的数据类型。要查找数据库中使用 unknown 数据类型的列,请运行以下查询:
SELECT DISTINCT data_type FROM information_schema.columns WHERE data_type ILIKE 'unknown';
(仅 RDS for PostgreSQL)检查只读副本升级是否失败
如果 PostgreSQL 实例有只读副本,则只读副本升级失败可能会导致您的主实例升级卡住或失败。Amazon RDS 将失效的只读副本设置为 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”。
要解决此问题,请使用不以 pg_ 开头的 rds_superuser 角色创建另一个用户。
检查是否存在不兼容的参数
当与内存相关的参数(例如 shared_buffer 或 work_memory)的值对于您的配置来说过高时,将会出现“incompatible parameters”错误。此错误会导致升级脚本失败。要解决此问题,请降低这些参数的值,然后再次执行升级。
在升级之前更新您的扩展
主要版本升级不会升级 PostgreSQL 扩展。如果您在主要版本升级之前未更新扩展,则会在 pg_upgrade.log 文件中收到类似于以下的错误消息:
“The Logs indicates that the RDS instance ''abcd'' 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_versionFROM pg_available_extensions WHERE installed_version IS NOT NULL AND name LIKE 'postgis%' OR name LIKE 'address%';
**注意:**请将 postgis% 替换为您的扩展。
如果 installed_version 的值低于 default_version 的值,则必须将 PostGIS 更新为默认版本。要升级您的扩展,请运行以下命令:
ALTER EXTENSION extension_name UPDATE TO 'default_version_number';
**注意:**将 default_version_number 替换为 default_version 值。
有关详细信息,请参阅升级 RDS for PostgreSQL 数据库引擎或升级 Amazon 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 中,PostgreSQL 将 waiting 列替换为 wait_event_type 和 wait_event 列。
或者,您可能会收到一条类似于以下的错误消息:
“pg_restore: from TOC entry abc; abc abcd 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".”
上述示例错误消息显示,错误是由于 PostgreSQL 版本 12 中 pg_constraint 目录的结构更改而导致的。
要解决这些问题,请删除基于目标版本系统目录的视图。
**重要事项:**在删除视图之前,最佳做法是使用 pgdump 来备份视图或捕获视图的定义。删除视图时,您或您的数据库管理员必须在版本升级后手动重新创建视图。
升级完成
升级完成后,对所有用户数据库运行 ANALYZE 以升级 pg_statistics 表。主要升级不会将 pg_statistics 表的内容移至新版本。如果您不移动内容,则可能会遇到查询运行缓慢的情况。
