← 中文资源

简体中文版本

为高更新表调优 autovacuum

观察死元组累积,计算真实更新速率,按表设置 scale factor 与成本限制,并验证膨胀曲线走平。

阅读英文原文

目标

autovacuum 并不神秘:死元组超过“scale×活元组+threshold”就触发,推进速度受 cost limit 与 delay 约束。千万行的表用默认 20% 阈值意味着攒够两百万死元组才开始清理。把真实更新速率代进这套算术,就能准确解释周五为什么慢、以及该改哪两个数字。

步骤要点

  1. 每小时两次采样 n_dead_tup 与 last_autovacuum 一整天,量化每小时四万死元组的更新速率。
  2. 手算默认触发点:0.2×1000 万+50≈200 万死元组,按 4 万/小时约 50 小时才触发,与每日churn严重失配。
  3. ALTER TABLE 设 scale_factor=0.01、threshold=10000、cost_limit=2000、cost_delay=1,约 70 分钟清理一次且每次能跑完。
  4. 观察 autovacuum_count 稳步上升、n_dead_tup 在低位振荡而非棘轮式攀升。
  5. 每周跟踪 pg_total_relation_size 趋势:体积稳定在小区间内即成功,周五的减速消失。

排错提示

清理总跑不完就调高该表 cost limit、把 delay 降到 1ms,并用 pg_stat_progress_vacuum 确认运行确实能结束;长事务会冻结清理进度,去 pg_stat_activity 找到并缩短它,或把长读移到副本;激进的按表设置会吃掉全局 worker 预算,应提高 autovacuum_max_workers 或只给极少数表开激进配置。

适用边界

表规模与负载变化后参数需要重估,应以趋势监控代替一次设定;autovacuum 只把空间标记复用、不会缩小文件,成功的判据是体积稳定而非下降。

代码示例

-- The trigger arithmetic
-- vacuum when: dead > scale * live + threshold
-- default:     dead > 0.2 * 10,000,000 + 50 = 2,000,050
-- churn 40k/h: fires every ~50 hours

ALTER TABLE events SET (
  autovacuum_vacuum_scale_factor = 0.01,
  autovacuum_vacuum_threshold = 10000,
  autovacuum_vacuum_cost_limit = 2000,
  autovacuum_vacuum_cost_delay = 1
);