manus-skills/.kortix/opencode/skills/coding/postgres/references/mvcc-vacuum.md
zhukang 1c7abd81d1 All 310 Manus skill-hub community skills as a Kortix marketplace registry
- 310 registry:skill items, 1528 files, 7 categories (hub tags)
- registry.json generated by @kortix/registry buildRegistry
- nested SKILL.md in sn-da-* renamed SUBSKILL.md (no phantom skills)
- provenance + licenses: SOURCES.md
2026-09-15 13:37:20 +08:00

2.5 KiB
Raw Blame History

title description tags
MVCC and VACUUM MVCC internals, VACUUM/autovacuum tuning, and bloat prevention postgres, mvcc, vacuum, autovacuum, xid, bloat, dead-tuples

MVCC and VACUUM

MVCC

Every UPDATE creates a new tuple and marks the old one dead; DELETE marks tuples dead. Dead tuples accumulate until VACUUM reclaims space. Each transaction gets a 32-bit XID (2^32 ≈ 4B values, but modular comparison means the effective danger zone is 2^31 ≈ 2B). VACUUM must freeze old XIDs to prevent wraparound.

VACUUM vs VACUUM FULL

VACUUM is non-blocking (ShareUpdateExclusive lock) and marks dead space reusable. VACUUM FULL rewrites the table and requires an AccessExclusive lock — use only as a last resort. For online bloat reduction prefer pg_squeeze or pg_repack.

Autovacuum Tuning

Triggers when dead tuples > Min(autovacuum_vacuum_max_threshold, autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * reltuples). autovacuum_vacuum_max_threshold defaults to 100M (PG 18+), capping the threshold for very large tables. Also triggers on inserts exceeding autovacuum_vacuum_insert_threshold + autovacuum_vacuum_insert_scale_factor * reltuples * pct_not_frozen (ensures insert-only tables get frozen; PG 13+). For large/hot tables, set per-table overrides:

  • autovacuum_vacuum_scale_factor — default 0.2; lower to 0.01–0.05 for large tables.
  • autovacuum_vacuum_cost_delay — default 2 ms; set to 0 on fast storage.
  • autovacuum_vacuum_cost_limit — default -1 (uses vacuum_cost_limit, effectively 200); raise to 1000–2000 on fast storage.
  • autovacuum_freeze_max_age — default 200M; triggers anti-wraparound vacuum.
  • vacuum_failsafe_age — default 1.6B; last-resort mode (PG 14+) that disables throttling and skips index vacuuming when wraparound is imminent.

Key Monitoring Queries

Dead tuples: SELECT relname, n_dead_tup, last_autovacuum FROM pg_stat_user_tables ORDER BY n_dead_tup DESC;

XID age: SELECT datname, age(datfrozenxid) AS xid_age FROM pg_database ORDER BY xid_age DESC;

Long transactions: SELECT pid, state, now() - xact_start AS tx_age FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY xact_start;

Best Practices

  • Keep transactions short; set idle_in_transaction_session_timeout (30s–5min).
  • Alert when age(datfrozenxid) exceeds 40–50% of wraparound (~800M–1B).
  • Tune autovacuum per-table for write-heavy tables; don't change global defaults first.
  • Fix application transaction scope before adjusting vacuum parameters.
  • Never disable autovacuum globally.