Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Beheben von Leistungsproblemen bei der Bereinigung in RDS für PostgreSQL
In diesem Abschnitt werden Faktoren erörtert, die häufig zu einer schlechteren Bereinigungsleistung führen. Zudem wird beschrieben, wie diese Probleme behoben werden können.
Themen
Bereinigen großer Indizes
Der VACUUM-Prozess durchläuft aufeinanderfolgende Phasen: Initialisierung, Heap-Scanning, Index- und Heap-Bereinigung, Indexsäuberung, Heap-Kürzung und abschließende Bereinigung. Während des Heap-Scans bereinigt der Prozess Seiten, defragmentiert sie und friert sie ein. Nach Abschluss des Heap-Scans bereinigt VACUUM Indizes, gibt leere Seiten an das Betriebssystem zurück und führt abschließende Aufgaben wie das Bereinigen der freien Speicherzuweisung und das Aktualisieren von Statistiken durch.
Das Bereinigen von Indizes kann mehrere Durchläufe erfordern, wenn maintenance_work_mem (oder autovacuum_work_mem) nicht ausreicht, um den Index zu verarbeiten. In PostgreSQL 16 und früheren Versionen bedingte ein Speicherlimit von 1 GB für das Speichern toter Tupel-IDs häufig mehrere Durchläufe großer Indizes. PostgreSQL 17 führt TidStore ein, sodass kein Array mit einer einzelnen Zuweisung verwendet, sondern Speicher dynamisch zugewiesen wird. Dadurch wird die Beschränkung auf 1 GB aufgehoben, der Arbeitsspeicher effizienter genutzt und der Bedarf an mehreren Index-Scans pro Index reduziert.
Große Indizes können in PostgreSQL 17 immer noch mehrere Durchläufe erfordern, wenn der verfügbare Speicher nicht die gesamte Indexverarbeitung auf einmal bewältigen kann. In der Regel enthalten größere Indizes mehr tote Tupel, für die mehrere Durchläufe erforderlich sind.
Erkennen langsamer Bereinigungsvorgänge
Die postgres_get_av_diag()-Funktion erkennt, wenn Bereinigungsvorgänge aufgrund unzureichenden Speichers langsam ausgeführt werden. Weitere Informationen zu dieser Funktionen finden Sie unter Installieren von Überwachungs- und Diagnosetools für die Selbstbereinigung in RDS für PostgreSQL.
Die postgres_get_av_diag()-Funktion gibt die folgenden Hinweise aus, wenn der verfügbare Speicher nicht ausreicht, um die Indexbereinigung in einem einzigen Durchgang abzuschließen.
rds_tools 1.8
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory.
Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
rds_tools 1.9
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more
memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual
vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see
Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide
.
Anmerkung
Die postgres_get_av_diag()-Funktion stützt sich auf pg_stat_all_tables.n_dead_tup, um die Menge an Speicher zu schätzen, der für die Indexbereinigung benötigt wird.
Wenn die postgres_get_av_diag()-Funktion einen langsamen Bereinigungsvorgang feststellt, für den mehrere Index-Scans erforderlich sind, weil autovacuum_work_mem nicht ausreicht, wird folgende Meldung generiert:
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming.
For more information, see Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide.
Empfehlungen
Sie können die folgenden Abhilfemaßnahmen mittels manuellem VACUUM FREEZE anwenden, um das Einfrieren der Tabelle zu beschleunigen.
Erhöhen des Speichers für die Bereinigung
Wie von der postgres_get_av_diag()-Funktion vorgeschlagen ist es ratsam, den autovacuum_work_mem-Parameter zu erhöhen, um möglichen Speicherbeschränkungen auf Instance-Ebene zu begegnen. Zwar ist autovacuum_work_mem ein dynamischer Parameter, dennoch muss beachtet werden, dass der Daemon für die Selbstbereinigung seine Worker neu starten muss, damit die neuen Speichereinstellungen wirksam werden. So können Sie dies erreichen:
-
Bestätigen Sie, dass die neue Einstellung festgelegt wurde.
-
Beenden Sie die Prozesse, die derzeit die Selbstbereinigung durchführen.
Dieser Ansatz stellt sicher, dass die angepasste Speicherzuweisung auf neue Selbstbereinigungsvorgänge angewendet wird.
Um unmittelbarere Ergebnisse zu erzielen, sollten Sie erwägen, manuell eine VACUUM FREEZE-Operation mit einer höheren maintenance_work_mem-Einstellung innerhalb Ihrer Sitzung durchzuführen:
SET maintenance_work_mem TO '1GB'; VACUUM FREEZE VERBOSEtable_name;
Wenn Sie Amazon RDS verwenden und feststellen, dass Sie zusätzlichen Speicher benötigen, um höhere Werte für maintenance_work_mem oder autovacuum_work_mem unterstützen zu können, sollten Sie ein Upgrade auf eine Instance-Klasse mit mehr Speicher in Betracht ziehen. Dadurch können die erforderlichen Ressourcen bereitgestellt werden, um sowohl die manuellen als auch die automatischen Bereinigungsvorgänge zu verbessern, was insgesamt zu einer verbesserten Bereinigungs- und Datenbankleistung führt.
Deaktivieren von INDEX_CLEANUP
Ein manuelles VACUUM in PostgreSQL-Version 12 und höher ermöglicht das Überspringen der Indexbereinigungsphase, während die Notfall-Selbstbereinigung in PostgreSQL-Version 14 und höher dies automatisch auf der Grundlage des Parameters vacuum_failsafe_age
Warnung
Das Überspringen der Indexbereinigung kann zu einer Aufblähung des Index führen und sich negativ auf die Abfrageleistung auswirken. Um dem entgegenzuwirken, sollten Sie erwägen, die betroffenen Indizes während eines Wartungsfensters neu zu indizieren oder zu bereinigen.
Weitere Anleitungen zum Umgang mit großen Indizes finden Sie in der Dokumentation zu Verwalten der automatischen Bereinigung mit großen Indizes .
Parallele Indexbereinigung
Ab PostgreSQL 13 können Indizes standardmäßig mit manuellem VACUUM parallel bereinigt und gesäubert werden, wobei jedem Index ein Bereinigungs-Worker zugewiesen wird. Damit PostgreSQL jedoch feststellen kann, ob ein Bereinigungsvorgang für eine parallele Ausführung infrage kommt, müssen bestimmte Kriterien erfüllt sein:
-
Es müssen mindestens zwei Indizes vorhanden sein.
-
Der
max_parallel_maintenance_workers-Parameter sollte auf mindestens 2 gesetzt werden. -
Die Indexgröße muss den
min_parallel_index_scan_size-Grenzwert überschreiten, der standardmäßig 512 KB beträgt.
Sie können die max_parallel_maintenance_workers-Einstellung auf der Grundlage der Anzahl der auf Ihrer Amazon-RDS-Instance verfügbaren vCPUs und der Anzahl der Indizes in der Tabelle anpassen, um die Bearbeitungszeit für das Bereinigen zu optimieren.
Weitere Informationen finden Sie unter Parallele Selbstbereinigung in Amazon RDS für PostgreSQL und Amazon Aurora PostgreSQL
Zu viele Tabellen oder Datenbanken zum Bereinigen
Wie in der PostgreSQL-Dokumentation Der Selbstbereinigungsdaemonautovacuum_naptime Sekunden pro Datenbank initiiert werden.
Bei „N“ Datenbanken startet ungefähr alle [autovacuum_naptime/N Sekunden] ein neuer Worker. Die Gesamtzahl der gleichzeitigen Worker ist jedoch durch die autovacuum_max_workers-Einstellung begrenzt. Wenn die Anzahl der Datenbanken oder Tabellen, die bereinigt werden müssen, diesen Grenzwert überschreitet, wird die nächste Datenbank oder Tabelle verarbeitet, sobald ein Worker verfügbar ist.
Wenn viele große Tabellen oder Datenbanken gleichzeitig bereinigt werden müssen, kann es sein, dass alle verfügbaren Bereinigungs-Worker für einen längeren Zeitraum ausgelastet sind, was die Wartung anderer Tabellen und Datenbanken verzögert. In Umgebungen mit hohen Transaktionsraten kann dieser Engpass schnell eskalieren und möglicherweise zu komplexeren Bereinigungsproblemen innerhalb Ihrer Amazon-RDS-Instance führen.
Wenn postgres_get_av_diag() eine große Anzahl von Tabellen oder Datenbanken erkennt, wird folgende Empfehlung bereitgestellt:
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
Empfehlungen
Erhöhen von autovacuum_max_workers
Um das Bereinigen zu beschleunigen, empfehlen wir, den autovacuum_max_workers-Parameter so anzupassen, dass mehr gleichzeitige Worker möglich sind. Wenn weiterhin Leistungsengpässe bestehen, sollten Sie erwägen, Ihre Amazon-RDS-Instance auf eine Klasse mit mehr vCPUs zu skalieren, wodurch die Möglichkeiten der Parallelverarbeitung weiter optimiert werden können.
Es läuft eine aggressive Bereinigung (um ein Wraparound zu verhindern)
Das Alter der Datenbank (MaximumUsedTransactionIDs) in PostgreSQL nimmt nur ab, wenn erfolgreich eine aggressive Bereinigung (zur Wraparound-Verhinderung) durchgeführt wird. Bis diese Bereinigung beendet ist, wird das Alter je nach Transaktionsrate weiter zunehmen.
Die postgres_get_av_diag()-Funktion generiert folgenden NOTICE, wenn sie eine aggressive Bereinigung erkennt. Sie löst diese Ausgabe jedoch erst aus, wenn die Bereinigung mindestens zwei Minuten lang aktiv war.
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
Weitere Informationen zu aggressivem Bereinigungen finden Sie unter Wenn bereits eine aggressive Bereinigung läuft.
Mit der folgenden Abfrage können Sie überprüfen, ob eine aggressive Bereinigung läuft:
SELECT a.xact_start AS start_time, v.datname "database", a.query, a.wait_event, v.pid, v.phase, v.relid::regclass, pg_size_pretty(pg_relation_size(v.relid)) AS heap_size, ( SELECT string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ') FROM pg_index i WHERE i.indrelid = v.relid ) AS index_sizes, trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct, v.index_vacuum_count || '/' || ( SELECT count(*) FROM pg_index i WHERE i.indrelid = v.relid ) AS step2_vacuum_indexes, trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct, age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar FROM pg_stat_activity a INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
Sie können anhand der Abfragespalte in der Ausgabe feststellen, ob es sich um eine aggressive Bereinigung (zur Wraparound-Verhinderung) handelt. Der Ausdruck „zur Wraparound-Verhinderung“ weist darauf hin, dass es sich um eine aggressive Bereinigung handelt.
query | autovacuum: VACUUM public.t3 (to prevent wraparound)
Angenommen, Sie haben einen Blocker mit einem Transaktionsalter von 1 Milliarde und eine Tabelle, die eine aggressive Bereinigung erfordert, um einen Wraparound im gleichen Transaktionsalter zu verhindern. Darüber hinaus gibt es einen weiteren Blocker mit einem Transaktionsalter von 750 Millionen. Nach der Aufhebung des Blockers mit einem Transaktionsalter von 1 Milliarde wird das Transaktionsalter nicht sofort auf 750 Millionen sinken. Es wird so lange hoch bleiben, bis die Tabelle, für die die aggressive Bereinigung erforderlich ist, oder eine andere Transaktion mit einem Alter von über 750 Millionen abgeschlossen ist. Während dieses Zeitraums wird das Transaktionsalter Ihres PostgreSQL-Clusters weiter steigen. Sobald der Bereinigungsvorgang abgeschlossen ist, wird das Transaktionsalter auf 750 Millionen sinken, aber es wird wieder steigen, bis das weitere Bereinigen abgeschlossen ist. Dieser Zyklus wird so lange fortgesetzt, wie diese Bedingungen bestehen, bis das Transaktionsalter schließlich auf das für Ihre Amazon-RDS-Instance konfigurierte Niveau fällt, das durch autovacuum_freeze_max_age angegeben ist.