EMZETT.
Login

PostgreSQL VACUUM: Autovacuum und aufgeblähte Tabellen

Kurz: PostgreSQL löscht Zeilen nicht sofort, sondern markiert sie; VACUUM räumt auf, gibt Platz zur Wiederverwendung frei und hält Statistiken aktuell, meist automatisch durch Autovacuum.

Genauer: Wegen MVCC (mehrere Versionen einer Zeile für parallele Transaktionen) erzeugen UPDATE und DELETE tote Zeilen (dead tuples). Sie bleiben, bis kein laufender Zugriff sie mehr braucht. VACUUM entfernt sie aus Sicht der Wiederverwendung.

Im Detail

Was VACUUM tut

  • Markiert Platz toter Zeilen als wiederverwendbar.
  • Aktualisiert die Sichtbarkeitskarte (beschleunigt Index-Only-Scans).
  • Schützt vor Transaction-ID-Wraparound (Einfrieren alter Zeilen).
  • VACUUM FULL schreibt die Tabelle neu und gibt Platz ans Betriebssystem zurück, sperrt aber exklusiv; selten nötig (Alternative: pg_repack).
  • ANALYZE sammelt Statistiken für den Abfrageplaner.

Autovacuum

Ein Hintergrundprozess startet VACUUM/ANALYZE, wenn genug Änderungen angefallen sind (Standard: 20 % der Tabelle + 50 Zeilen). Einstellungen: autovacuum_vacuum_scale_factor, autovacuum_naptime, pro Tabelle ALTER TABLE … SET (autovacuum_vacuum_scale_factor = 0.02). Nie abschalten. Bei großen, stark geänderten Tabellen aggressiver konfigurieren.

Bloat erkennen

Symptome: Tabelle/Index wächst trotz gleicher Datenmenge, Abfragen werden langsamer. Prüfen: pg_stat_user_tables (n_dead_tup, last_autovacuum), Größe mit pg_total_relation_size, Erweiterung pgstattuple. Ursachen: lange Transaktionen oder vergessene offene Verbindungen (verhindern Aufräumen), zu seltenes Autovacuum, häufige Massenupdates. Lösung: Transaktionen kurz halten, Autovacuum feiner einstellen, manuell VACUUM (VERBOSE, ANALYZE) tabelle;.

Praxis und verwaltete Dienste

Bei Neon, Supabase, RDS läuft Autovacuum meist automatisch; trotzdem Muster beobachten (Tabellen mit vielen Updates wie Sitzungen, Zähler, Warteschlangen: lieber Insert + Löschen alter Zeilen oder Partitionen). Löschen großer Mengen in Batches. Backup vor VACUUM FULL. Lies pg_stat_progress_vacuum. Verbindungen, die in idle in transaction hängen, sind Feinde jedes Vacuums: mit idle_in_transaction_session_timeout begrenzen.

Siehe auch: PostgreSQL, MVCC und Isolationsstufen, PostgreSQL-Indizes, Connection Pooling