如何排查 Aurora PostgreSQL 实例中的本地存储问题?

上次更新日期:2021 年 9 月 30 日

我想排查 Amazon Aurora PostgreSQL 兼容版实例中的本地存储问题。

简短描述

Amazon Aurora 集群中的数据库实例有两种存储类型:

  • 用于持久性数据的存储(共享集群卷)。有关详细信息,请参阅集群卷包含的内容
  • 集群中每个 Aurora 实例基于实例类的本地存储。此存储大小取决于实例类,只有在移动至较大数据库实例类时才能更改。Aurora PostgreQL 兼容版使用本地存储来存储错误日志和临时文件。

解决方法

您可使用 Amazon CloudWatch 中的 FreeLocalStorage 指标,监控与 Aurora 数据库实例或节点相关的本地存储空间。该指标报告每个数据库实例中可用于临时表和日志的存储数量。有关更多信息,请参阅使用 Amazon CloudWatch 监控 Amazon Aurora 指标

如果您的 Aurora 本地存储已满,请参阅下面的错误消息和问题排查步骤:

本地存储空间用于存储临时表或文件

“错误:无法写入临时文件的数据块 XXXXXXXX:设备上没有剩余空间。”

在数据库实例上用尽临时存储空间时,可能会发生此错误。修改大型表、在大型表上添加索引的操作或者使用复杂 JOIN、GROUP BY 或 ORDER BY 子句执行大型 SELECT 查询的操作可能会导致这些错误。

您可以使用下列方法来检查临时表和临时文件大小:

1.    对于临时文件,在 Aurora PostgreSQL 兼容版的数据库实例上启用 log_temp_files 参数。此参数记录大小超过指定的千字节数的临时文件使用情况。启用此参数后,删除每个临时文件时将会为该文件创建一个日志条目。值为 0 将记录所有临时文件信息。正值仅记录大于或等于指定千字节数的文件。原定设置值为 -1,这将关闭临时文件日志记录。您可以使用此参数来识别临时文件详细信息,然后您可以将这些临时文件与 FreeLocalStorage 指标关联。

注意:启用 log_temp_files 参数可能导致 Aurora PostgreSQL 兼容版的数据库实例上的日志记录过多。因此,最佳实践是在启用 log_temp_files 之前检查 Aurora PostgreSQL 兼容版的日志文件大小。如果 Aurora PostgreSQL 兼容版的日志文件消耗的本地存储空间最多,则您可以通过降低 rds.log_retention 参数的值回收空间。rds.log_retention 的原定设置值为三天。

您还可以通过以下命令的后续运行指示的增量查看临时文件的情况:

maxiops=> select datname, temp_files , pg_size_pretty(temp_bytes) as temp_file_size  FROM   pg_stat_database order by temp_bytes desc;

注意:temp_files 列中,所有临时文件都计算在内 – 无论您何时创建的临时文件(例如,通过排序或散列)。视图 pg_stat_database 中的 temp_filestemp_bytes 列收集累积值的统计数据。该值可利用 pg_stat_reset() 函数或通过重启数据库实例来重置。有关详细信息,请参阅 PostgreSQL 文档了解有关其他统计函数的信息。

注意:如果您使用 Aurora PostgreSQL 兼容版或者 Amazon RDS for PostgreSQL 10 或更高版本,则可以使用性能详情监控 temp_bytestemp_files。除了等待事件外,性能详情还提供数据库引擎内部指标的本机计数器。有关更多信息,请参阅 Amazon RDS PostgreSQL 本机计数器

您还可以升高 maintenance_work_memwork_mem 以向执行操作的进程分配更多内存。这样会将更多内存用于该操作,使其可以使用更少的临时磁盘存储。有关这些参数的更多信息,请参阅 maintenance_work_mem 和 work_mem 的 PostgreSQL 文档。最佳实践是在查询或会话层设置 maintenance_work_memwork_mem 的值,以避免耗尽内存。有关详细信息,请参阅 Amazon Aurora PostgreSQL 参考

2.    对于临时表,运行与以下内容类似的查询:

maxiops=> SELECT
n.nspname as SchemaName
,c.relname as RelationName
,CASE c.relkind
WHEN 'r' THEN 'table'
WHEN 'v' THEN 'view'
WHEN 'i' THEN 'index'
WHEN 'S' THEN 'sequence'
WHEN 's' THEN 'special'
END as RelationType
,pg_catalog.pg_get_userbyid(c.relowner) as RelationOwner
,pg_size_pretty(pg_relation_size(n.nspname ||'.'|| c.relname)) as RelationSize
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n
    ON n.oid = c.relnamespace
WHERE  c.relkind IN ('r','s')
AND  (n.nspname !~ '^pg_toast' and nspname like 'pg_temp%')
ORDER BY pg_relation_size(n.nspname ||'.'|| c.relname) DESC;

最佳实践是密切监控应用程序并查看哪些事务创建了临时表。通过这样做,您可以管理可用本地存储容量的使用情况。您还可以将您的 Aurora 实例迁移到更高的实例类,以使实例获得更多的可用本地存储。

日志文件使用的本地存储

过多的日志记录也可能导致您的数据库实例耗尽本地存储。以下是可能占用本地存储空间的日志记录参数的一些示例。消耗空间可能是由于记录过多或错误日志保留时间过长。

rds.log_retention_period
auto_explain.log_min_duration
log_connections
log_disconnections
log_lock_waits
log_min_duration_statement
log_statement
log_statement_stats

要确定哪个参数导致了过多的日志记录,分析 PostgreSQL 日志以找出最大的日志。然后,确定这些日志中的大多数条目由哪个参数导致。接下来,您可以修改导致日志记录过多的参数。如果您重复运行的查询失败并生成错误,PostgreSQL 在原定设置情况下会将这些错误记录到 PostgreSQL 错误日志中。查看记录的错误,然后修复失败的查询,以防止日志使用过多的存储。您还可以降低 rds.log_retention 的原定设置值(三天),以回收空间。

您还可以升高您的 Aurora 数据库实例的大小,以使数据库实例获得更多的可用本地存储。


这篇文章对您有帮助吗?


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