了解对无效数据库使用 autovacuum 的行为
在 pg_database
目录的 datconnlimit
列中引入了一个新值 -2
,来指示在 DROP DATABASE 操作过程中已被中断的数据库为无效的。
以下 RDS for PostgreSQL 版本中提供了这个新值:
15.4 及所有更高版本
14.9 及更高版本
13.12 及更高版本
12.16 及更高版本
11.21 及更高版本
无效的数据库不会影响 autovacuum 冻结有效数据库的功能的能力。Autovacuum 会忽略无效的数据库。因此,对于 PostgreSQL 环境中的所有有效数据库,常规 vacuum 操作将继续正常且高效地运行。
监控事务 ID
age(datfrozenxid)
函数常用于监控数据库的事务 ID(XID)期限,以防止事务 ID 重叠。
由于无效数据库被排除在 autovacuum 之外,因此其事务 ID(XID)计数器可以达到最大值 2 billion
,重叠到 - 2 billion
,并无限期地继续此循环。监控事务 ID 重叠的典型查询可能如下所示:
SELECT max(age(datfrozenxid)) FROM pg_database;
但是,在为 datconnlimit
引入 -2 值后,无效的数据库可能会扭曲此查询的结果。由于这些数据库无效,而不应作为定期维护检查的一部分,因此它们可能会导致误报,致使您认为 age(datfrozenxid)
高于实际值。
调整监控查询
为确保准确的监控,应调整监控查询来排除无效的数据库。请遵循这一建议的查询:
SELECT max(age(datfrozenxid)) FROM pg_database WHERE datconnlimit <> -2;
此查询可确保在 age(datfrozenxid)
计算中只考虑有效的数据库,从而真实地反映整个 PostgreSQL 环境中的事务 ID 期限。
解决无效的数据库问题
当尝试连接到无效的数据库时,可能会遇到类似于以下内容的错误消息:
postgres=> \c db1 connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL: cannot connect to invalid database "db1" HINT: Use DROP DATABASE to drop invalid databases. Previous connection kept
此外,如果 log_min_messages
参数设置为 DEBUG2
或更高,您可能会注意到以下日志条目,表明 autovacuum 进程正在跳过无效的数据库:
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG: autovacuum: skipping invalid database "db6" 2024-07-30 05:59:00 UTC::@:[32000]:DEBUG: autovacuum: skipping invalid database "db1"
要解决此问题,请按照尝试连接期间提供的 HINT
进行操作。使用 RDS 主账户或具有 rds_superuser
角色的数据库账户连接到任何有效的数据库,然后删除无效的数据库。
SELECT 'DROP DATABASE ' || quote_ident(datname) || ';' FROM pg_database WHERE datconnlimit = -2 \gexec