本节探讨了可能阻碍清理取得进展的其他原因。postgres_get_av_diag()
函数目前无法直接识别这些问题。
页面无效
当 PostgreSQL 在访问页面时检测到该页面的校验和不匹配时,就会出现无效页面错误。内容无法读取,从而阻止自动真空冻结元组。这样实际上会停止清理过程。PostgreSQL 的日志中写入了以下错误:
WARNING: page verification failed, calculated checksum YYYYY but expected XXXX
ERROR: invalid page in block ZZZZZ of relation base/XXXXX/XXXXX
CONTEXT: automatic vacuum of table myschema.mytable
确定对象类型
ERROR: invalid page in block 4305910 of relation base/16403/186752608
WARNING: page verification failed, calculated checksum 50065 but expected 60033
从错误消息中,路径 base/16403/186752608
提供以下信息:
-
“base”是 PostgreSQL 数据目录下的目录名称。
-
“16403”是数据库 OID,您可以在
pg_database
系统目录中进行查找。 -
“186752608”是
relfilenode
,您可以使用它在pg_class
系统目录中查找架构和对象名称。
通过在受影响的数据库中检查以下查询的输出,可以确定对象类型。以下查询会检索 oid 为 186752608 的对象信息。将该 OID 替换为与您遇到的错误相关的 OID。
SELECT
relname AS object_name,
relkind AS object_type,
nspname AS schema_name
FROM
pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
c.oid = 186752608;
有关更多信息,请参阅 PostgreSQL 文档 pg_class
pg_class
中的 relkind
列所示。
指南
此问题的最有效解决方案取决于特定 Amazon RDS 实例的配置以及受不一致页面影响的数据类型。
如果对象类型是索引:
建议重建索引。
-
使用
CONCURRENTLY
选项 – 在 PostgreSQL 版本 12 之前,重建索引需要独占的表锁定,从而限制对表的访问。在 PostgreSQL 版本 12 及更高版本中,CONCURRENTLY
选项允许行级别锁定,从而显著提高表的可用性。命令如下:REINDEX INDEX
ix_name
CONCURRENTLY;虽然
CONCURRENTLY
的破坏性较小,但在繁忙的表中其速度可能会变慢。如果可能,可以考虑在流量较低的时段构建索引。有关更多信息,请参阅 PostgreSQL REINDEX
文档。 -
使用
INDEX_CLEANUP FALSE
选项 – 如果索引很大并且估计需要大量时间才能完成,则您可以通过在排除索引的同时执行手动VACUUM FREEZE
来解除阻止自动真空。PostgreSQL 版本 12 及更高版本中提供了此功能。绕过索引将允许您跳过索引不一致的真空过程并缓解重叠问题。但是,这样并不能解决潜在的无效页面问题。要完全应对和解决无效页面问题,您仍然需要重建索引。
如果对象类型为实体化视图:
如果实体化视图上出现无效页面错误,请登录到受影响的数据库并刷新以解决无效的页面:
刷新实体化视图:
REFRESH MATERIALIZED VIEW schema_name.materialized_view_name;
如果刷新失败,请尝试重新创建:
DROP MATERIALIZED VIEW schema_name.materialized_view_name;
CREATE MATERIALIZED VIEW schema_name.materialized_view_name AS query;
刷新或重新创建实体化视图可在不影响基础表数据的情况下还原该视图。
对于所有其他对象类型:
对于所有其他对象类型,请联系 AWS 支持。
索引不一致
逻辑上不一致的索引可能会阻碍自动真空取得进展。在索引的真空阶段或 SQL 语句访问索引时,将记录以下错误或类似错误。
ERROR: right sibling's left-link doesn't match:block 5 links to 10 instead of expected 2 in index ix_name
ERROR: failed to re-find parent key in index "XXXXXXXXXX" for deletion target page XXX
CONTEXT: while vacuuming index index_name
of relation schema.table
指南
在手动 VACUUM FREEZE
上使用 INDEX_CLEANUP
重建索引或跳过索引。有关如何重建索引的信息,请参阅如果对象类型是索引。
事务速率异常高
在 PostgreSQL 中,事务速率高会显著影响自动真空的性能,从而导致无效元组的清理速度变慢,并增加事务 ID 重叠的风险。您可以通过衡量两个时间段之间的 max(age(datfrozenxid))
差异(通常为每秒)来监控事务速率。此外,您还可以使用 RDS 性能详情中的以下计数器指标来衡量事务速率(xact_commit 与 xact_rollback 之和),即事务总数。
计数器 | 类型 | 单位 | 指标 |
---|---|---|---|
xact_commit |
事务 |
每秒提交数 |
db.Transactions.xact_commit |
xact_rollback |
事务 |
每秒回滚数 |
db.Transactions.xact_rollback |
快速增加表示高事务负载,这可能会使自动真空不堪重负,从而导致膨胀、锁争用和潜在的性能问题。这样可能会以多种方式对自动真空进程产生负面影响:
-
表活动:正在经历清理操作的特定表可能会遇到大量事务,从而导致延迟。
-
系统资源:整个系统可能会过载,使自动真空难以访问必要的资源以便高效运行。
请考虑以下策略,以允许自动真空更有效地运行并跟上其任务:
-
如果可能,请降低事务速率。请考虑在可行的情况下对类似的事务进行批处理或分组。
-
在非高峰时段,每晚、每周或每两周通过手动
VACUUM FREEZE
操作来定位频繁更新的表。 -
请考虑扩展您的实例类以分配更多系统资源来处理高事务量和自动真空操作。