one relation demonstrably misses its maintenance window
its write pattern differs materially from cluster norm
change rate and resource budget are measured
override is in schema/IaC and reviewed
不适合:
copy every global GUC to every table
set autovacuum_enabled=false as tuning
hide a long-transaction blocker
raise freeze age to silence alerts
eligible tables waiting
active autovacuum workers
worker phase
disk latency / queue
CPU busy / run queue
buffer and cache effect
business p95/p99
replica and archive lag
session 结束即回退;没有修改集群配置。10 ms 是教学限速,不是推荐生产值。官方文档
指出正常配置通常应使用很小的 delay,大延迟并不理想。
I/O 不是唯一竞争
vacuum 还会:
read heap
dirty heap / VM / FSM
read and update indexes
generate WAL for maintenance changes
use CPU to evaluate tuple visibility
acquire relation/page locks
evict useful shared/OS cache pages
所以 “iowait 不高” 不能证明 vacuum 无影响。可能:
数据在 cache,竞争表现为 CPU 和 buffer churn;
device 很快,竞争表现为 foreground tail;
cloud storage queue 未映射为 host iowait;
cost delay 让 worker 大量 sleep;
checkpoint/backup 与 vacuum 交织。
维护优先级不是一刀切
可把对象分三层:
P0 correctness:
XID/MXID danger
suspected corruption
P1 service health:
dead tuple backlog accelerating
index cleanup not completing
table growth threatens disk/SLO
P2 efficiency:
moderate bloat
stale statistics
low HOT ratio
initializing
scanning heap
vacuuming indexes
vacuuming heap
cleaning up indexes
truncating heap
performing final cleanup
解释时注意:
heap_blks_total 是开始扫描时的规模;
VM 跳过的块仍会计入 scanned 的推进;
heap_blks_vacuumed 可能跳跃;
index 可能有多个 cycle;
truncation、锁等待和 index cleanup 的耗时不由 heap 扫描百分比线性预测。
所以:
heap_blks_scanned / heap_blks_total
是 scan progress,不是可靠 ETA。
“没清掉”的决策树
Did VACUUM run?
├─ no
│ ├─ below threshold
│ ├─ worker unavailable
│ ├─ autovacuum/table option disabled
│ ├─ statistics not updating
│ └─ permissions/manual command skipped relation
└─ yes
├─ old snapshot still needs tuples
├─ replication slot xmin/catalog_xmin retains them
├─ prepared transaction retains horizon/locks
├─ index cleanup skipped/deferred
├─ pages skipped to avoid waits
├─ only estimate is stale
├─ space became reusable but file did not shrink
└─ new churn arrived as fast as cleanup
blocker inventory
SELECTpid,usename,application_name,state,xact_start,state_change,backend_xid,backend_xmin,age(backend_xid)ASxid_age,age(backend_xmin)ASxmin_age,wait_event_type,wait_eventFROMpg_stat_activityWHEREbackend_xidISNOTNULLORbackend_xminISNOTNULLORstateLIKE'idle in transaction%'ORDERBYage(backend_xmin)DESCNULLSLAST;
when did it start?
is it accelerating?
which instance/table changed?
what else happened at the same time?
原生 SQL 回答:
which PID and phase now?
which exact xmin/slot/prepared xact retains horizon?
which reloption and effective GUC applies?
两者必须互证。Grafana panel 不是另一个数据库真相层。
处置顺序
1. classify correctness vs service vs efficiency
2. verify actual trigger inputs and table overrides
3. locate active/queued workers and progress
4. inventory holders
5. compare cleanup rate with churn rate
6. check I/O/CPU/memory/WAL/replica side effects
7. choose smallest reversible intervention
8. validate dead/reusable/age outcome
9. record desired state and rollback
跳过第 4 步直接“手工再 vacuum 一次”,通常只会重复同一失败。
本节检查清单
effective update/delete threshold
effective insert threshold
analyze threshold
freeze/MXID age
table reloptions
eligible backlog
worker slots / max workers
per-worker and total memory budget
cost limit distribution
progress phase and cycle
old snapshot/slot/2PC holders
foreground tail and device pressure
cleanup rate vs churn rate