Wraparound-Schutz mit Transaktions-ID (TXID) überwinden

Auf dieser Seite wird gezeigt, was Sie tun können, wenn für Ihre Datenbank der Transaktions-ID-Wraparound-Schutz in PostgreSQL ausgelöst wird. Das wird folgendermaßen als ERROR-Meldung ausgegeben:

database is not accepting commands to avoid wraparound data loss in database
dbname.

Stop the postmaster and vacuum that database in single-user mode.

You might also need to commit or roll back old prepared transactions, or drop
stale replication slots.

Alternativ wird eventuell eine WARNING-Meldung wie die folgende angezeigt:

database dbname must be vacuumed within 10985967 transactions.

To avoid a database shutdown, execute a database-wide VACUUM in that database.

Die einzelnen Schritte im Überblick

  • Finden Sie heraus, welche Datenbank und welche Tabellen den Wraparound-Status verursachen.
  • Prüfen Sie, ob etwas zurückgehalten wird (AUTO)VACUUM (z. B. eine festhängende Transaktions-ID).
  • Messen Sie die Geschwindigkeit von AUTOVACUUM. Wenn sie langsam ist, können Sie versuchen, sie zu beschleunigen.
  • Führen Sie bei Bedarf weitere VACUUM-Befehle manuell aus.
  • Suchen Sie nach anderen Möglichkeiten zur Beschleunigung von Vacuum. Manchmal ist es am schnellsten, die Tabelle oder einige Indexe zu löschen.

Viele Empfehlungen für Werte von Flags sind absichtlich allgemein gehalten, da sie von vielen Datenbankparametern abhängen. Ausführlichere Informationen zu diesem Thema erhalten Sie in den Dokumenten, die am Ende dieser Seite verlinkt sind.

Datenbank und Tabelle suchen, die den Wraparound verursacht

Datenbank suchen

Führen Sie die folgende Abfrage aus, um herauszufinden, welche Datenbank(n) die Tabellen enthalten, die den Wraparound-Status verursachen:

SELECT datname,
       age(datfrozenxid),
       2^31-1000000-age(datfrozenxid) as remaining
  FROM pg_database
 ORDER BY 3

Die Datenbank mit dem remaining-Wert nahe 0 ist die Datenbank, die das Problem verursacht.

Tabelle suchen

Stellen Sie eine Verbindung zur Datenbank her und führen Sie die folgende Abfrage aus:

SELECT c.relnamespace::regnamespace as schema_name,
       c.relname as table_name,
       greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age,
       2^31-1000000-greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as remaining
  FROM pg_class c
  LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
 WHERE c.relkind IN ('r', 'm')
 ORDER BY 4;

Diese Abfrage gibt die Tabelle oder die Tabellen zurück, die das Problem verursachen.

Bei TEMPORARY-Tabellen

Wenn schema_name mit pg_temp_ beginnt, besteht die einzige Möglichkeit zur Lösung des Problems darin, die Tabelle zu löschen, da PostgreSQL keine VACUUM-Tabellen zulässt, die in anderen Sitzungen erstellt wurden. Wenn diese Sitzung offen und zugänglich ist, können Sie die Tabelle dort entfernen, aber dies ist oft nicht der Fall. Verwenden Sie die folgenden SQL-Anweisungen, um die temporäre Tabelle zu löschen:

SET cloudsql.enable_maintenance_mode = 'on'; /* get extra transaction ids */
DROP TABLE pg_temp_<N>.<tablename>;

Wenn dies die einzige Blockierung war, verschiebt Autovacuum innerhalb einer Minute die datfrozenxid in pg_database. Dadurch wird der schreibgeschützte Wraparound-Schutz gelöst.

Normale Tabellen

Bei normalen (nicht temporären) Tabellen fahren Sie mit den nächsten Schritten fort, um zu sehen, ob die Bereinigung durch etwas blockiert wird, ob VACUUM schnell genug ausgeführt wird und ob die entscheidende Tabelle bereinigt worden ist.

Auf festhängende Transaktions-ID prüfen

Ein möglicher Grund dafür, dass dem System keine Transaktions-IDs mehr zur Verfügung stehen, besteht darin, dass PostgreSQL keine Transaktions-IDs mehr fixieren (d. h. für alle Transaktionen als sichtbar kennzeichnen) kann, die erstellt wurden, nachdem die älteste Transaktion gestartet wurde, die derzeit ausgeführt wird. Dies ist auf MVCC-Regeln (Multiversion Concurrency Control) zurückzuführen. In extremen Fällen können solche Transaktionen so alt sein, dass sie mit VACUUM nicht mehr für das gesamte Limit für den Transaktions-ID-Wraparound von 2 Milliarden bereinigt werden können. Das gesamte System akzeptiert dann die neue DML nicht mehr. In der Regel werden dann in der Logdatei auch Warnungen mit dem Text WARNING: oldest xmin is far in the past angezeigt.

Sie sollten mit der Optimierung erst fortfahren, nachdem das Problem mit der festhängenden Transaktions-ID behoben wurde.

Im Folgenden finden Sie vier mögliche Ursachen für das Festhängen der Transaktions-ID sowie Informationen dazu, wie Sie diese beheben können:

  • Lang andauernde Transaktionen: Ermitteln Sie sie und beenden Sie das Backend, um die Blockierung des Vacuum aufzuheben.
  • Verwaiste Vorbereitungstransaktionen: Führen Sie ein Rollback dieser Transaktionen aus.
  • Verworfene Replikationsslots: Entfernen Sie die verworfenen Slots.
  • Lang andauernde Transaktion auf dem Replikat mit hot_standby_feedback = on: Ermitteln Sie diese und brechen Sie das Backend ab bzw. beenden Sie es, um die Blockierung des Vacuum-Vorgangs aufzuheben.

In diesen Szenarien gibt die folgende Abfrage das Alter der ältesten Transaktion sowie die Anzahl der Transaktionen zurück, die bis zum Wraparound verbleiben:

 WITH q AS (
SELECT
  (SELECT max(age(backend_xmin))
      FROM pg_stat_activity  WHERE state != 'idle' )       AS oldest_running_xact_age,
  (SELECT max(age(transaction)) FROM pg_prepared_xacts)    AS oldest_prepared_xact_age,
  (SELECT max(greatest(age(catalog_xmin),age(xmin))) FROM pg_replication_slots)        AS oldest_replication_slot_age,
  (SELECT max(age(backend_xmin)) FROM pg_stat_replication) AS oldest_replica_xact_age
)
SELECT *,
       2^31 - oldest_running_xact_age AS oldest_running_xact_left,
       2^31 - oldest_prepared_xact_age AS oldest_prepared_xact_left,
       2^31 - oldest_replication_slot_age AS oldest_replication_slot_left,
       2^31 - oldest_replica_xact_age AS oldest_replica_xact_left
FROM q;

Diese Abfrage gibt eventuell die *_left-Werte zurück, die in der Nähe des Werts von 1 Million oder für weniger als 1 Million des Wraparound-Schutzlimits erfasst wurden. Dieser Wert ist das Limit für den Wraparound-Schutz, ab dem PostgreSQL keine neuen Schreibbefehle mehr akzeptiert. Dazu finden Sie weitere Informationen unter VACUUM-Blöcke entfernen und VACUUM optimieren.

Die vorherige Abfrage kann beispielsweise Folgendes zurückgeben:

┌─[ RECORD 1 ]─────────────────┬────────────┐
│ oldest_running_xact_age      │ 2146483655 │
│ oldest_prepared_xact_age     │ 2146483655 │
│ oldest_replication_slot_age  │ ¤          │
│ oldest_replica_xact_age      │ ¤          │
│ oldest_running_xact_left     │ 999993     │
│ oldest_prepared_xact_left    │ 999993     │
│ oldest_replication_slot_left │ ¤          │
│ oldest_replica_xact_left     │ ¤          │
└──────────────────────────────┴────────────┘

Dabei liegen oldest_running_xact_left und oldest_prepared_xact_left innerhalb des 1-Millionen-Wraparound-Schutzlimits. In diesem Fall müssen Sie zuerst die Blockierung für VACUUM aufheben, damit Sie fortfahren können.

VACUUM-Blockierung entfernen

Lang andauernde Transaktionen

Wenn in der vorherigen Abfrage oldest_running_xact gleich oldest_prepared_xact ist, wechseln Sie zum Abschnitt der verwaisten Vorbereitungstransaktion, da der Wert für Aktuell ausgeführt auch die vorbereiteten Transaktionen beinhaltet.

Möglicherweise müssen Sie zuerst den folgenden Befehl als postgres-Nutzer ausführen:

GRANT pg_signal_backend TO postgres;

Wenn die betreffende Transaktion zu einem der Systemnutzer gehört (beginnend mit cloudsql...), können Sie sie nicht direkt abbrechen. Sie müssen die Datenbank neu starten, um sie abzubrechen.

Wenn Sie eine lange andauernde Abfrage ermitteln und abbrechen oder beenden möchten, um die Blockierung von Vacuum aufzuheben, wählen Sie als Erstes einige der ältesten Abfragen aus. Die LIMIT 10-Linie ermöglicht die Anpassung des Ergebnisses an den Bildschirm. Sie müssen dies möglicherweise wiederholen, nachdem Sie die am längsten andauernden Abfragen aufgelöst haben.

SELECT pid,
       age(backend_xid) AS age_in_xids,
       now() - xact_start AS xact_age,
       now() - query_start AS query_age,
       state,
       query
 FROM pg_stat_activity
 WHERE state != 'idle'
 ORDER BY 2 DESC
 LIMIT 10;

Wenn age_in_xids den Wert NULL hat, wurde der Transaktion keine permanente Transaktions-ID zugewiesen und sie kann problemlos ignoriert werden.

Brechen Sie die Abfragen ab, bei denen sich der xids_left_to_wraparound 1 Million nähert.

Wenn state active ist, kann die Abfrage mit SELECT pg_cancel_backend(pid); abgebrochen werden. Andernfalls müssen Sie die gesamte Verbindung mithilfe von SELECT pg_terminate_backend(pid); beenden, wobei pid die pid der vorherigen Abfrage ist.

Verwaiste Vorbereitungstransaktionen

So listen Sie alle vorbereiteten Transaktionen auf:

DB_NAME=> SELECT age(transaction),* FROM pg_prepared_xacts ;
┌─[ RECORD 1 ]┬───────────────────────────────┐
│ age         │ 2146483656                    │
│ transaction │ 2455493932                    │
│ gid         │ trx_id_pin                    │
│ prepared    │ 2021-03-03 16:54:07.923158+00 │
│ owner       │ postgres                      │
│ database    │ DB_NAME                       │
└─────────────┴───────────────────────────────┘

Führen Sie ein Rollback der ältesten verwaisten vorbereiteten Transaktionen aus. Dazu verwenden Sie gid aus der letzten Abfrage (in diesem Fall trx_id_pin) als Transaktions-ID:

ROLLBACK PREPARED trx_id_pin;

Alternativ können Sie einen Commit ausführen:

COMMIT PREPARED trx_id_pin;

Eine ausführliche Erläuterung finden Sie in der Dokumentation SQL ROLLBACK PREPARED.

Verworfene Replikationsslots

Wenn der Replikationsslot verworfen wird, da das vorhandene Replikat entweder beendet wurde, pausiert oder ein anderes Problem aufweist, können Sie das Replikat aus gcloud oder aus der Google Cloud Console löschen.

Prüfen Sie zuerst, ob das Replikat wie auf der Seite Lesereplikate verwalten beschrieben deaktiviert ist. Wenn das Replikat deaktiviert ist, aktivieren Sie es wieder. Wenn die Verzögerung weiterhin hoch bleibt, löschen Sie das Replikat.

Die Replikationsslots sind in der Systemansicht pg_replication_slots sichtbar.

Die folgende Abfrage ermittelt die relevanten Informationen:

SELECT *, age(xmin) AS age FROM pg_replication_slots;
┌─[ RECORD 1 ]────────┬─────────────────────────────────────────────────┐
│ slot_name           │ cloudsql_1_355b114b_9ff4_4bc3_ac88_6a80199bd738 │
│ plugin              │ ¤                                               │
│ slot_type           │ physical                                        │
│ datoid              │ ¤                                               │
│ database            │ ¤                                               │
│ active              │ t                                               │
│ active_pid          │ 1126                                            │
│ xmin                │ 2453745071                                      │
│ catalog_xmin        │ ¤                                               │
│ restart_lsn         │ C0/BEF7C2D0                                     │
│ confirmed_flush_lsn │ ¤                                               │
│ age                 │ 59                                              │
└─────────────────────┴─────────────────────────────────────────────────┘

In diesem Beispiel ist der Wert für pg_replication_slots akzeptabel (Alter = 59). Wenn das Alter fast 2 Milliarden beträgt, sollten Sie den Slot löschen. Es gibt keine einfache Möglichkeit, Replikate zu identifizieren, wenn die Abfrage mehrere Datensätze zurückgibt. Prüfen Sie sie daher genau, wenn für ein Replikat eine lang andauernde Transaktion ausgeführt wird.

Lang andauernde Transaktionen für Replikate

Prüfen Sie Replikate auf die älteste ausgeführte Transaktion mit dem Wert on für hot_standby_feedback und deaktivieren Sie sie für das Replikat.

Die Spalte backend_xmin in der Ansicht pg_stat_replication enthält die älteste TXID, die für das Replikat benötigt wird.

Um fortzufahren, beenden Sie die Abfrage, die die Blockierung für das Replikat verursacht. Um zu ermitteln, welche Abfrage die Blockierung verursacht, verwenden Sie die Abfrage aus dem Abschnitt Lang andauernde Transaktionen, diesmal jedoch für das Replikat.

Eine weitere Möglichkeit besteht darin, das Replikat neu zu starten.

VACUUM konfigurieren

Legen Sie die beiden folgenden Flags fest:

  • autovacuum_vacuum_cost_delay = 0
  • autovacuum_work_mem = 1048576

Das erste Flag deaktiviert alle Laufwerks-Drosselungen für das Vacuuming durch PostgreSQL, sodass VACUUM mit maximaler Geschwindigkeit ausgeführt werden kann. Standardmäßig wird Autovacuum gedrosselt, sodass es auf den langsamsten Servern nicht die gesamte Laufwerks-E/A-Kapazität beansprucht.

Das zweite Flag autovacuum_work_mem verringert die Anzahl der Indexbereinigungsdurchläufe. Der Wert dafür sollte nach Möglichkeit groß genug gewählt werden, um alle IDs von toten Zeilen in einer Tabelle, die durch VACUUM bereinigt wird, speichern zu können. Beachten Sie beim Festlegen dieses Werts, dass dies der maximale Umfang von lokalem Arbeitsspeicher ist, den jeder ausgeführte VACUUM-Vorgang zuweisen kann. Achten Sie darauf, dass Sie nicht mehr zulassen, als verfügbar ist. Es sollte auch weitere Kapazität in Reserve vorhanden sein. Wenn die Datenbank weiter im schreibgeschützten Modus ausgeführt wird, sollte dabei auch der für schreibgeschützte Abfragen genutzte lokale Arbeitsspeicher berücksichtigt werden.

Verwenden Sie für die meisten Systeme den Höchstwert (1 GB oder 1.048.576 KB, wie im Beispiel gezeigt). Dieser Wert reicht für ungefähr 178 Millionen tote Tupel. Höhere Werte führen dazu, dass mehrere Indexscans ausgeführt werden.

Dieses und andere Flags werden ausführlich unter VACUUM-Vorgänge in PostgreSQL optimieren, überwachen und korrigieren erläutert.

Nachdem Sie diese Flags festgelegt haben, starten Sie die Datenbank neu, damit Autovacuum die neuen Werte nutzt.

In der Ansicht pg_stat_progress_vacuum können Sie den Fortschritt der von Autovacuum gestarteten VACUUM-Vorgänge überwachen. Diese Ansicht zeigt VACUUM-Vorgänge, die in allen Datenbanken ausgeführt werden, und für Tabellen (Verweise) aus anderen Datenbanken, für die der Tabellenname nicht über die Ansichtsspalte relid abgerufen werden kann.

Um die Datenbanken und Tabellen zu ermitteln, die als Nächstes geleert werden müssen, verwenden Sie die Abfragen unter VACUUM-Vorgänge in PostgreSQL optimieren, überwachen und korrigieren. Wenn die Server-VM ausreichend leistungsfähig ist und Bandbreite für mehr parallele VACUUM-Vorgänge hat als von Autovacuum gestartet wurden, können Sie einige manuelle Vacuum-Vorgänge starten.

VACUUM-Geschwindigkeit prüfen

In diesem Abschnitt wird gezeigt, wie Sie die Geschwindigkeit von VACUUM prüfen und bei Bedarf erhöhen können.

Laufende Autovacuums prüfen

Alle Back-Ends, auf denen VACUUM-Vorgänge ausgeführt werden, werden in der Systemansicht pg_stat_progress_vacuum angezeigt.

Wenn die aktuelle Phase scanning heap ist, können Sie den Fortschritt beobachten, indem Sie Änderungen in der Spalte heap_blks_scanned beobachten. Allerdings gibt es keine einfache Möglichkeit, um die Scangeschwindigkeit in anderen Phasen zu bestimmen.

VACUUM-Scangeschwindigkeit schätzen

Zum Schätzen der Scangeschwindigkeit müssen Sie zuerst die Basiswerte speichern und dann die Änderung im Zeitablauf berechnen, um den Zeitaufwand für die Ausführung zu schätzen. Als Erstes müssen Sie mit der folgenden Snapshot-Abfrage einen Snapshot von heap_blks_scanned zusammen mit einem Zeitstempel speichern:

SELECT set_config('save.ts', clock_timestamp()::text, false),
       set_config('save.heap_blks_scanned', heap_blks_scanned::text, false)
FROM pg_stat_progress_vacuum
WHERE datname = 'DB_NAME';

Da nichts in Tabellen gespeichert werden kann, was sich bereits im Wraparound befinden, verwenden Sie set_config(flag, value), um für zwei benutzerdefinierte Flags – save.ts und save.heap_blks_scanned – die aktuellen Werte von pg_stat_progress_vacuum festzulegen.

In der nächsten Abfrage nutzen wir diese beiden Werte als Vergleichsbasis, um die Geschwindigkeit zu bestimmen und den Zeitaufwand für die Ausführung zu schätzen.

HINWEIS: WHERE datname = DB_NAME beschränkt die Untersuchung auf jeweils eine Datenbank. Dies ist ausreichend, wenn in dieser Datenbank nur ein Autovacuum mit mehr als einer Zeile pro Datenbank ausgeführt wird. Um eine einzelne Autovacuum-Zeile anzugeben, müssen der WHERE-Klausel zusätzliche Filterbedingungen (('AND relid= …'')) hinzugefügt werden. Dies gilt auch für die nächste Abfrage.

Nachdem Sie die Basiswerte gespeichert haben, können Sie die folgende Abfrage ausführen:

with q as (
    SELECT datname,
           phase,
           heap_blks_total,
           heap_blks_scanned,
           clock_timestamp() - current_setting('save.ts')::timestamp AS ts_delta,
           heap_blks_scanned - current_setting('save.heap_blks_scanned')::bigint AS scanned_delta
     FROM pg_stat_progress_vacuum
     WHERE datname = DB_NAME
), q2 AS (
SELECT *,
       scanned_delta / extract('epoch' FROM ts_delta) AS pages_per_second
  FROM q
)
SELECT *,
       (heap_blks_total - heap_blks_scanned) / pages_per_second AS remaining_time
  FROM q2
;
┌─[ RECORD 1 ]──────┬──────────────────┐
│ datname           │ DB_NAME          │
│ phase             │ scanning heap    │
│ heap_blks_total   │ 9497174          │
│ heap_blks_scanned │ 18016            │
│ ts_delta          │ 00:00:40.30126   │
│ as_scanned_delta  │ 11642            │
│ pages_per_second  │ 288.87434288655  │
│ remaining_time    │ 32814.1222418038 │
└───────────────────┴──────────────────┘

Diese Abfrage vergleicht die aktuellen Werte mit den Speicherbasiswerten und berechnet pages_per_second und remaining_time. Damit lässt sich entscheiden, ob VACUUM schnell genug ausgeführt wird oder ob es beschleunigt werden muss. Der Wert für remaining_time gilt nur für die Phase scanning heap. Andere Phasen erfordern ebenfalls Zeitaufwand, manchmal sogar noch mehr. Sie können weitere Informationen zum Vacuuming aufrufen und sich in Blogposts im Internet informieren, die komplexe Aspekte von Vacuum-Vorgängen diskutieren.

VACUUM beschleunigen

Der einfachste und schnellste Weg, um den VACUUM-Scan zu beschleunigen, ist die Festlegung von autovacuum_vacuum_cost_delay=0. Dies ist über die Google Cloud Console möglich.

Allerdings übernimmt der bereits ausgeführte VACUUM-Vorgang diesen Wert nicht und Sie müssen die Datenbank möglicherweise neu starten.

Nach einem Neustart sehen Sie eventuell ein Ergebnis ähnlich dem folgenden:

┌─[ RECORD 1 ]──────┬──────────────────┐
│ datname           │ DB_NAME          │
│ phase             │ scanning heap    │
│ heap_blks_total   │ 9497174          │
│ heap_blks_scanned │ 222382           │
│ ts_delta          │ 00:00:21.422615  │
│ as_scanned_delta  │ 138235           │
│ pages_per_second  │ 6452.76031894332 │
│ remaining_time    │ 1437.33713040171 │
└───────────────────┴──────────────────┘

In diesem Beispiel wurde die Geschwindigkeit von < 300 Seiten/Sek. auf etwa 6.500 Seiten/Sekunde erhöht. Die erwartete verbleibende Zeit für den Heap-Scan ist von 9 Stunden auf 23 Minuten gesunken.

Die Scangeschwindigkeit der anderen Phasen ist nicht so einfach messbar. Es sollte dafür aber eine ähnliche Beschleunigung erreicht worden sein.

Versuchen Sie außerdem, autovacuum_work_mem so groß wie möglich festzulegen, um mehrere Indexdurchläufe zu vermeiden. Ein Indexdurchlauf wird jedes Mal ausgeführt, wenn im Arbeitsspeicher Zeiger toter Tupel vorhanden sind.

Wenn die Datenbank nicht anderweitig verwendet wird, legen Sie autovacuum_work_mem so fest, dass ca. 80 % des Arbeitsspeichers frei bleibt, nachdem Sie für shared_buffers den erforderlichen Wert freigegeben haben. Dies ist die Obergrenze für jeden mit Autovacuum gestarteten VACUUM-Prozess. Wenn Sie weiterhin schreibgeschützte Arbeitslasten ausführen möchten, empfiehlt es sich, weniger Arbeitsspeicher zu verwenden.

Weitere Möglichkeiten zur Verbesserung der Geschwindigkeit

Bereinigung von Indexen vermeiden

Bei großen Tabellen braucht VACUUM die meiste Zeit für die Bereinigung der Indexe.

PostgreSQL 14 bietet spezielle Optimierungen, um die Indexbereinigung zu vermeiden, wenn die Gefahr besteht, dass das System in den Wraparound-Status versetzt wird.

In PostgreSQL 12 und 13 können Sie die folgende Anweisung manuell ausführen:

VACUUM (INDEX_CLEANUP OFF, TRUNCATE OFF) <tablename>;

In Versionen ab 11 können Sie den Index mit DROP löschen, bevor Sie Vacuum ausführen und ihn später neu erstellen.

Einen Index zu löschen, wenn bereits Autovacuum für diese Tabelle ausgeführt wird, erfordert es, den laufenden Vacuum-Vorgang abzubrechen und dann sofort den Befehl zum Löschen des Index auszuführen, bevor Autovacuum den Vacuum-Vorgang für diese Tabelle wieder neu startet.

Führen Sie zuerst die folgende Anweisung aus, um die PID des Autovacuum-Vorgangs zu ermitteln, den Sie beenden müssen:

SELECT pid, query
  FROM pg_stat_activity
 WHERE state != 'idle'
   AND query ilike '%vacuum%';

Führen Sie dann die folgenden Anweisungen aus, um den laufenden Autovacuum-Vorgang zu beenden und einen oder mehrere Indexe zu löschen:

SET cloudsql.enable_maintenance_mode = 'on'; /* get extra transaction ids */
SELECT pg_terminate_backend(<pid>);DROP INDEX <index1>;DROP INDEX <index2>; ...

Betroffene Tabelle löschen

In seltenen Fällen können Sie die Tabelle löschen. Dies ist beispielsweise möglich, wenn die Tabelle einfach aus einer anderen Quelle wie einer Sicherung oder einer anderen Datenbank wiederhergestellt werden kann.

Sie müssen weiterhin cloudsql.enable_maintenance_mode = 'on' verwenden und wahrscheinlich auch den Vacuum-Vorgang für diese Tabelle beenden, wie im vorherigen Abschnitt gezeigt.

VACUUM FULL

In seltenen Fällen ist die Ausführung von VACUUM FULL FREEZE schneller, in der Regel, wenn die Tabelle nur einen kleinen Teil von Live-Tupeln enthält. Dies kann in der Ansicht pg_stat_user_tables geprüft werden, sofern kein Absturz aufgetreten ist, der die Statistiken gelöscht hat.

Der Befehl VACUUM FULL kopiert Live-Tupel in eine neue Datei. Daher muss für die neue Datei und ihre Indexe genügend Speicherplatz verfügbar sein.

Nächste Schritte