标准答案
- 先从 pg_stat_user_tables 查看 n_dead_tup、n_live_tup、n_mod_since_analyze、last_autovacuum、last_autoanalyze,以及当前表和索引大小,确认是清理滞后还是统计信息滞后。
- 大表按默认 scale factor 触发时,可能需要积累大量变更才开始清理;可以按热点表设置更合适的 autovacuum_vacuum_scale_factor、threshold 和 analyze 参数。
- VACUUM 主要处理旧版本、可复用空间、可见性和冻结;ANALYZE 更新规划器统计信息。查询计划变差时,只加 vacuum worker 不一定能解决问题。
- worker、cost delay 和 cost limit 需要结合磁盘吞吐、复制延迟、业务峰值和其他后台任务调节,不能为了追求清理速度把 I/O 打满。
- 如果长事务或复制槽让旧版本无法回收,调小阈值也不会从根本上解决;应先处理阻塞回收的事务和复制消费者。
题目解析
autovacuum 是持续维护机制,不是一次性修复命令。它既要足够及时地清理版本和更新统计,也不能在业务高峰持续争抢全部 I/O。
排查时要先区分“没有触发”“触发了但跑不完”“跑完仍无法回收”三种情况:阈值、资源不足和长事务对应的修复路径完全不同。
比较调参效果时应观察 dead tuples、表膨胀、查询计划、I/O、复制延迟和业务 P99,而不是只看 last_autovacuum 时间变新。
常见误区
- 误区:关闭 autovacuum,改成业务低峰手工执行。改正:手工维护无法稳定覆盖所有表和异常路径,应该先按表调参并监控。
- 误区:只增加 autovacuum worker。改正:worker 增多可能与业务查询、WAL 和复制争抢资源,必须结合 I/O 和清理进度验证。
- 误区:把 ANALYZE 当作 VACUUM。改正:ANALYZE 更新统计信息,不能代替旧版本回收;两者都可能影响查询性能但解决的问题不同。