测量事务 ID 回卷风险(按数据库和表的 XID 年龄)
PostgreSQL维护命令
-- Per database: distance to autovacuum_freeze_max_age and the ~2^31 limit
SELECT datname,
age(datfrozenxid) AS xid_age,
mxid_age(datminmxid) AS mxid_age,
round(100.0 * age(datfrozenxid) / current_setting('autovacuum_freeze_max_age')::int, 1) AS pct_of_freeze_max_age,
round(100.0 * age(datfrozenxid) / 2147483647, 1) AS pct_of_wraparound
FROM pg_database
ORDER BY age(datfrozenxid) DESC;
-- Oldest tables in the current database (including TOAST)
SELECT c.oid::regclass AS table_name,
greatest(age(c.relfrozenxid), age(t.relfrozenxid)) AS xid_age,
mxid_age(c.relminmxid) AS mxid_age,
pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,
s.last_autovacuum,
s.last_vacuum
FROM pg_class c
LEFT JOIN pg_class t ON t.oid = c.reltoastrelid
LEFT JOIN pg_stat_all_tables s ON s.relid = c.oid
WHERE c.relkind IN ('r', 'm')
ORDER BY 2 DESC
LIMIT 20;作用
显示每个数据库最旧的未冻结 XID 和 multixact 年龄相对于 autovacuum_freeze_max_age 和回卷上限的比例;在当前数据库中,列出最旧的表(包括 TOAST)及其大小和最近一次 vacuum 时间。
适用场景
用于例行监控(典型阈值:pct_of_wraparound 50% 警告 / 75% 严重)、日志显示 'must be vacuumed within N transactions' 时,以及确定 freeze 工作的优先级。
注意
对于 pct_of_freeze_max_age 超过 100 的表,autovacuum 会启动强制(防回卷)vacuum;它 I/O 很重,即使被终止也会重新启动。如果年龄不下降,原因几乎总是有东西阻碍了 xmin horizon(长事务、prepared transaction、复制槽、hot_standby_feedback);请先解决它,否则即使 VACUUM FREEZE 也无法降低年龄。接近上限时,服务器先发出警告,当只剩几百万时会拒绝分配新的 XID(写入)。针对性 freeze:VACUUM (FREEZE, VERBOSE) <table>;