Wie behebe ich die Selbstbereinigung, wenn in Datenbanken von Amazon RDS für PostgreSQL oder von Aurora PostgreSQL-Compatible das Flag „to prevent wraparound“ aktiviert wird?
Ich möchte Leistungsprobleme lösen, wenn die Selbstbereinigung in meiner Datenbank von Amazon Relational Database Service (Amazon RDS) für PostgreSQL oder von Amazon Aurora PostgreSQL-Compatible Edition das Flag „to prevent wraparound“ aktiviert.
Kurzbeschreibung
Wenn du pg_stat_activity abfragst, führt autovacuum möglicherweise ständig das Flag „to prevent wraparound“ aus.
Selbstbereinigungs-Worker blockieren im Allgemeinen keine anderen Befehle. Wenn ein Prozess versucht, eine Sperre zu erwerben, die mit der SHARE UPDATE EXCLUSIVE-Sperre der Selbstbereinigung in Konflikt steht, kann der Sperrenerwerb die Selbstbereinigung unterbrechen. Wenn die Selbstbereinigung jedoch ausgeführt wird, um einen Wraparound der Transaktions-ID zu verhindern, unterbricht das System die Selbstbereinigung nicht automatisch.
In den folgenden Szenarien kann es zur aggressiven Selbstbereinigung mit dem Flag „to prevent wraparound“ kommen:
- Der relfrozenxid-Wert der Tabelle ist größer als der Wert von vacuum_freeze_table_age-Transaktionen; daher führt das System eine aggressive Bereinigung durch, um alte Tupel einzufrieren und relfrozenxid weiterzuleiten.
- Eine Tabelle erreicht ihr autovacuum_freeze_max_age.
Probleme mit der Datenbankleistung können auftreten, wenn die Selbstbereinigung aggressiv ausgeführt wird. Weitere Informationen findest du unter Automatic vacuuming (Automatisches Bereinigen) auf der PostgreSQL-Website.
Lösung
Feststellen, ob die Selbstbereinigung ausgeführt wird
Führe die folgende Abfrage aus, um festzustellen, ob die Selbstbereinigung ausgeführt wird, wie lange sie ausgeführt wird oder ob sie wartet:
SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY xact_start;
In der folgenden Beispielausgabe wird das Flag „to prevent wraparound“ auf mydb für mytable1 und mytable2 ausgeführt:
datname | usename | pid | state | wait_event | xact_runtime | query --------+----------+-------+--------+------------+-------------------------+---------------------------------------------------------------------------------------------- mydb | rdsadmin | 16473 | active | | 33 days 16:32:11.600656 | autovacuum: VACUUM ANALYZE public.mytable1 (to prevent wraparound) mydb | rdsadmin | 22553 | active | | 14 days 09:15:34.073141 | autovacuum: VACUUM ANALYZE public.mytable2 (to prevent wraparound) mydb | rdsadmin | 41909 | active | | 3 days 02:43:54.203349 | autovacuum: VACUUM ANALYZE public.mytable3 mydb | rdsadmin | 618 | active | | 00:00:00 | SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query+ | | | | | | FROM pg_stat_activity + | | | | | | WHERE query like '%VACUUM%'+ | | | | | | ORDER BY xact_start; +
Die Selbstbereinigung zielt immer auf die Tabellen ab, deren relfrozenxid größer ist als die Anzahl der Transaktionen in autovaccum_freeze_max_age.
Nicht eingefrorene Transaktionen identifizieren
Führe die folgende Abfrage aus, um nicht eingefrorene Transaktionen in deiner Datenbank zu identifizieren:
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
In der folgenden Beispielausgabe priorisiert der Selbstbereinigungs-Deamon die Datenbank mit einer datfrozenxid, die größer als 200 Millionen ist:
datname | age mydb | 1771757888 template0 | 1721757888 template1 | 1721757888 rdsadmin | 1694008527 postgres | 1693881061 (5 rows)
Die Spalte datfrozenxid der Zeile pg_database einer Datenbank befindet sich am Ende der normalen Transaktions-IDs in der Datenbank. Die Spalte datfrozenxid ist das Minimum der relfrozenxid-Werte für jede Tabelle in der Datenbank.
Die Tabellen einfrieren
Wenn deine Tabelle das maximale relfrozenxid-Tabellenalter erreicht, führe eine manuelle Bereinigungseinfrierung der Tabellen durch.
Nachdem die manuelle Bereinigungseinfrierung abgeschlossen ist, kannst du anhand der ausführlichen Ausgabe feststellen, ob es Blockaden gibt, z. B. alte Replikationsslots und vorbereitete Transaktionen. Wenn du die Meldung „DETAIL: xxx dead row versions cannot be removed yet, oldest xmin: xxx“ erhältst, dann läuft die Bereinigung, kann aber die ungültigen Tupel nicht bereinigen.
Um die Bereinigungsblocker zu finden, kannst du die Funktion postgres_get_av_diag() verwenden. Weitere Informationen findest du unter Identifizieren und Beheben aggressiver Bereinigungsblocker in RDS für PostgreSQL.
Die Anzahl der Selbstbereinigungs-Worker erhöhen und ungenutzte Indizes entfernen
Wenn die Datenbanken oder Tabellen, die bereinigt werden müssen, das autovacuum_max_workers-Kontingent überschreiten, verarbeitet die Engine die nächste Datenbank oder Tabelle erst, wenn ein Worker verfügbar wird. In Umgebungen mit hohen Transaktionsraten können Probleme mit der Wraparound-Bereinigung auftreten.
Um dieses Problem zu beheben, erhöhe den Parameter autovacuum_max_workers, sodass mehr Selbstbereinigungs-Worker gleichzeitig vorhanden sind.
Wenn die Tabelle große Indizes enthält, empfiehlt es sich, nicht verwendete Indizes zu entfernen.
Erhöhen der Bereinigungsspeicher
Erhöhe den Parameter autovacuum_work_mem, um sicherzustellen, dass die Engine die angepasste Speicherzuweisung auf neue Selbstbereinigungen anwendet.
Führe den folgenden Befehl aus, um den maintenance_work_mem für manuelle Bereinigungsvorgänge wie Bereinigungseinfrierungen zu erhöhen:
SET maintenance_work_mem TO '2GB';
Hinweis: Der Standardwert für maintenance_work_mem ist 64 MB. Wenn die Bereinigung abgeschlossen ist, ändere den Wert auf den vorherigen Wert. Wenn du den Wert nicht änderst, können Speicherprobleme bei kleineren Instance-Größen auftreten.
Führe den folgenden Befehl aus, um den Bereinigungsvorgang zu starten:
VACUUM FREEZE VERBOSE table_name;
Wenn es große Indizes gibt, die bereinigt werden müssen, muss die Selbstbereinigung mehrere Durchläufe durchführen. In PostgreSQL 16 und früheren Versionen gibt es ein maintenance_work_mem-Kontingent von 1 GB, das der Bereinigungsvorgang verwendet. PostgreSQL 17 und neuere Versionen verwenden TidStore, der dynamisch Speicher zuweist und kein Array mit nur einer Zuweisung verwendet, sodass die Bereinigung maintenance_work_mem effizienter nutzen kann.
Paralleles Bereinigen aktivieren
Für eine manuelle Bereinigung kannst du das parallele Bereinigen aktivieren, sodass PostgreSQL jedem Index einen Bereinigungs-Worker zuweist und ihn parallel bereinigt.
Um die parallele Bereinigung zu aktivieren, passe die Einstellung max_parallel_maintenance_workers basierend auf der Anzahl der verfügbaren vCPUs für deine DB-Instance und der Anzahl der Indizes in der Tabelle an.
Weitere Informationen findest du unter Paralleles Bereinigen in Amazon RDS für PostgreSQL und Amazon Aurora PostgreSQL.
Die Anzahl der Transaktionen überwachen, die deine Datenbank verwendet hat
Wenn der Selbstbereinigungsvorgang eine Bereinigung nicht abschließen kann, wird die Datenbank möglicherweise weiter vergrößert. Du kannst die Amazon-CloudWatch-Metrik MaximumUsedTransactionIDs verwenden, um die Anzahl der maximalen Transaktionen abzurufen, die die Datenbank verwendet hat.
Erstelle außerdem einen CloudWatch-Alarm für die MaximumUsedTransactionIDs-Metrik, der dich benachrichtigen soll, wenn die Anzahl der Transaktionen den von dir angegebenen Wert erreicht. Weitere Informationen findest du unter Implementieren eines Frühwarnsystems für den Transaktions-ID-Wraparound in Amazon RDS für PostgreSQL.
Gehe wie folgt vor, um MaximumUsedTransactionIDs auf der Amazon-RDS-Konsole zu überwachen:
- Öffne die Amazon-RDS-Konsole.
- Wähle im Navigationsbereich Datenbanken und dann deine Datenbank aus.
- Auf der Registerkarte Protokolle und Ereignisse kannst du MaximumUsedTransactionIDs im Abschnitt Aktuelle Ereignisse anzeigen.
Wenn du das MaximumUsedTransactionIDs-Kontingent erreichst, musst du die Tabelle bereinigen.
Informationen zur Identifizierung der Bereinigungsblocker findest du unter Identifizieren und Beheben aggressiver Bereinigungsblocker in RDS für PostgreSQL.
- Themen
- Database
- Sprache
- Deutsch

Relevanter Inhalt
AWS OFFICIALAktualisiert vor 10 Monaten