PG 19 垃圾回收变聪明了,不信看这个视图
痛点回顾:数据库越来越慢,autovacuum 到底在忙什么?哪些表该先清理?XID 年龄有没有风险?以前只能靠猜。
现在,一个新视图让这一切都透明了。
01 这个视图能干啥?
pg_stat_autovacuum_scores,名字很长,但功能很直接—— 它给每个表打了一个"紧急程度分" 。
分数越高,说明这个表越急需 autovacuum 处理。
SELECT relname, score, vacuum_score, xid_score
FROM pg_stat_autovacuum_scores
ORDERBY score DESC
LIMIT10;
结果大概长这样:
relname | score | vacuum_score | xid_score
--------------+-------+--------------+------------
orders | 1.85 | 1.85 | 0.00
users | 0.95 | 0.95 | 0.00
user_sessions| 0.85 | 0.00 | 0.85
orders 表分数 1.85,说明死元组堆积严重;user_sessions 虽然死元组不多,但 XID 年龄偏高,可能有 wraparound 风险。
02 分数是怎么算出来的?
不是简单看死元组数量,而是一个多维度评分机制:
总分取各组件的最大值——哪个最严重,就按哪个处理。
这解释了为什么有时候死元组不多的表,反而分数很高:因为它的 XID/MXID 年龄可能已经接近警戒线了。
03 实战场景
场景一:揪出 XID wraparound 高风险表
SELECT * FROM pg_stat_autovacuum_scores
WHERE xid_score > 0.8OR for_wraparound = true
ORDERBY xid_score DESC;
如果 XID 耗尽,数据库将无法写入新数据——这是 PostgreSQL 最严重的事故之一。现在能精确定位到具体是哪张表。
场景二:理解多表竞争时的处理顺序
当 autovacuum worker 只有 1 个槽位,但 10 张表都需要清理时,它会按分数从高到低处理。
想知道你的表为什么迟迟没被 vacuum?查一下分数就知道了。
场景三:调优 autovacuum 参数
如果想让 autovacuum 优先处理表膨胀(而非 freeze 年龄):
ALTERSYSTEMSET autovacuum_vacuum_score_weight = 2.0;
ALTERSYSTEMSET autovacuum_freeze_score_weight = 0.5;
SELECT pg_reload_conf();
调优前后的分数变化,可以量化验证效果。
04 告警这样配
-- 高风险:XID 分数 > 0.8 或 for_wraparound = true
CREATEORREPLACEFUNCTION check_autovacuum_risk()
RETURNSvoidAS $$
DECLARE
risk_count INTEGER;
BEGIN
SELECTCOUNT(*) INTO risk_count
FROM pg_stat_autovacuum_scores
WHERE xid_score > 0.8OR for_wraparound = true;
IF risk_count > 0 THEN
RAISE WARNING '⚠️ % 张表需要立即关注 autovacuum', risk_count;
ENDIF;
END;
$$ LANGUAGE plpgsql;
配合 pg_cron 或外部监控工具,实现自动告警。
05 一句话总结
以前:autovacuum 是黑箱,DBA 只能被动等事故。
现在:有了 pg_stat_autovacuum_scores,谁该先清理、为什么、有多紧急,一目了然。
推荐配置:将高分数表的查询纳入日常巡检,特别是 xid_score 持续走高的表,提前处理远比事后补救划算得多。