it-swarm.com.de

Wie lange dauert ein Vakuum- / Autovakuumbetrieb?

Ich verwalte eine große Datenbank (einige Hundert Gigs) mit Tabellen mit verschiedenen Rollen, von denen einige Millionen von Datensätzen enthalten. Einige Tabellen erhalten nur eine große Anzahl von Einfügungen und Löschungen, andere wenige Einfügungen und eine große Anzahl von Aktualisierungen.

Die Datenbank läuft unter PostgreSQL 8.4 auf einem Debian 6.0 AMD64-System mit 16 Gigabyte RAM.

Die Frage ist manchmal Autovakuum-Prozess auf einem Tisch, dauert sehr lange (Tage), um abzuschließen. Ich möchte grob sagen können, wie viel Zeit ein bestimmter Vakuumbefehl benötigt, um entscheiden zu können, ob er abgebrochen werden soll oder nicht. Auch wenn es eine Fortschrittsanzeige für Postgres-Vakuumoperationen gäbe, wäre dies sehr hilfreich.

Bearbeiten:

Ich suche keine kugelsichere Lösung. Nur ein grober Hinweis auf die Anzahl der toten Tupel oder der erforderlichen E/A-Bytes reicht aus, um zu entscheiden. Es ist wirklich ärgerlich, keine Ahnung zu haben, wann VACUUM überhaupt fertig sein wird.

Ich habe gesehen, dass pg_catalog.pg_stat_all_tables hat eine Spalte für die Anzahl der toten Tupel. Es ist also möglich, eine Schätzung zu haben, selbst wenn dies bedeutet, dass man die Tabelle vorher ANALYZE muss. Auf der anderen Seite, autovacuum_vacuum_threshold und autovacuum_vacuum_scale_factor Einstellungen allein beweisen, dass postgres selbst weiß etwas über das Ausmaß der Änderungen in den Tabellen und legt es wahrscheinlich auch in die Hände des DBA.

Ich bin nicht sicher, welche Abfrage ausgeführt werden soll, denn wenn ich VACUUM VERBOSE, Ich sehe, dass nicht nur Tabellen, sondern auch Indizes auf ihnen verarbeitet werden.

18
zaadeh

Auf meinem PostgreSQL (8.3) verwende ich diesen Trick:

  1. Ich erhalte die Festplattengröße der Tabelle mit pg_total_relation_size() - dies schließt Indizes und die TOAST-Größe ein, was VACUUM verarbeitet. Dies gibt mir die Idee, wie viele Bytes das VACUUM lesen muss.
  2. Ich führe VACUUM auf dem Tisch aus.
  3. Ich finde das pid des VACUUM Prozesses (in pg_catalog.pg_stat_activity).
  4. In Linux Shell starte ich while true; do cat /proc/123/io | grep read_bytes; sleep 60; done (wo 123 is the pid) - Dies zeigt mir die Bytes, die der Prozess bisher von der Festplatte gelesen hat.

Dies gibt mir eine ungefähre Vorstellung davon, wie viele Bytes jede Minute vom VACUUM verarbeitet (gelesen) werden. Ich gehe davon aus, dass VACUUM die gesamte Tabelle (einschließlich Indizes und TOAST) lesen muss, deren Festplattengröße ich aus Schritt 1 kenne.

Ich gehe davon aus, dass die Tabelle groß genug ist, so dass der Großteil der Seiten von der Festplatte gelesen werden muss (sie sind nicht im gemeinsam genutzten Postgres-Speicher vorhanden), also die read_bytes Feld ist gut genug, um als Fortschrittszähler verwendet zu werden.

Jedes Mal, wenn ich dies tat, betrug die Gesamtzahl der vom Prozess gelesenen Bytes nicht mehr als 5% der gesamten Beziehungsgröße. Ich denke, dieser Ansatz ist möglicherweise gut genug für Sie.

35
Roman Hocke

Dies ist sehr schwer zu bestimmen. Sie können das Autovakuum einstellen m aggressiver zu sein oder um milder zu sein. Wenn es jedoch auf mild eingestellt ist und hinterherhinkt und die Basis-E/A-Last zu hoch ist, kann es vorkommen, dass es nie einen ordnungsgemäßen Vakuumzustand erreicht - dann sehen Sie, wie der Prozess läuft und läuft und läuft. Darüber hinaus haben spätere PostreSQL-Editionen die Autovacuum-Funktionen erheblich verbessert. Dies allein kann ausreichen, um zu einer von ihnen zu wechseln (vorzugsweise 9.2 als neueste Version).

Der Fortschrittsbalken klingt nach einer guten Idee, aber ich kann mir vorstellen, dass es nicht so einfach ist, ihn sinnvoll umzusetzen. Da Ihre Tabellen ständig belastet sind, ist es durchaus möglich, dass der Fortschritt anscheinend rückwärts geht (ich meine, dass die Anzahl/der Prozentsatz der toten Zeilen zunimmt, anstatt abzunehmen) - welche Schlussfolgerung ziehen Sie dann?

9
dezso

Ich fand dieser Beitrag und dieser Beitrag hilfreich, aber wie andere bereits erwähnt haben, kann es schwierig sein, den Gesamtfortschritt des Vakuums zu berechnen, da der Prozess einige separate Operationen umfasst.

Ich verwende diese Abfrage, um den Fortschritt des Scannens von Vakuumtischen zu überwachen, was den größten Teil der Arbeit ausmacht:

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

Dies schließt jedoch nicht das Index-Scannen ein, das danach erfolgt, und kann genauso lange, wenn nicht sogar länger dauern, wenn Sie eine Menge Indizes haben. Leider kann ich das Scannen/Staubsaugen von Indizes nicht überwachen.

4
Cerin

In unserer Produktion hatte einer der größten Tische dieses Protokoll:

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

Dies ist bei weitem der schlechteste Ressourcenverbrauch, alle anderen Tabellen haben weniger als 2 s gedauert.

Um diese Arten von Protokollen anzuzeigen, sollten Sie Folgendes ausführen:

alter system set log_autovacuum_min_duration TO 5; 

(für 5 ms) Laden Sie die Konfigurationsdatei neu.

3
stonelazy