it-swarm.com.de

Was passiert im PostgreSQL-Checkpoint?

Hier ist ein Teil meines Checkpoint-Protokolls:

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

Mir ist aufgefallen, dass unsere Datenbank manchmal sehr langsam ist - Sie können eine sehr große Anzahl von normalerweise kurzen Abfragen sehen, die viel länger als jetzt hängen bleiben. Es passiert regelmäßig ohne einen klaren Schuldigen.

Frage: Könnte Checkpoint dies verursachen? Was passiert in der "Synchronisierungs" -Phase des Checkpoints?

22
Konrad Garus

Während des Betriebs zeichnet PostgreSQL Änderungen an Transaktionsprotokolldateien auf, löscht sie jedoch nicht sofort in die tatsächlichen Datenbanktabellen. Normalerweise werden die Änderungen nur im Speicher gespeichert und bei Anforderung aus dem Speicher zurückgegeben, es sei denn, RAM wird langsam voll und muss ausgeschrieben werden).

Dies bedeutet, dass bei einem Absturz die On-Disk-Tabellen nicht auf dem neuesten Stand sind. Es muss die Transaktionsprotokolle erneut abspielen und die Änderungen auf die Datenträgertabellen anwenden, bevor es wieder gestartet werden kann. Dies kann für eine große, ausgelastete Datenbank eine Weile dauern.

Aus diesem Grund und damit die Transaktionsprotokolle nicht für immer wachsen, führt PostgreSQL regelmäßig einen Prüfpunkt durch, an dem sichergestellt wird, dass sich die Datenbank in einem sauberen Zustand befindet. Es löscht alle ausstehenden Änderungen auf der Festplatte und recycelt die Transaktionsprotokolle, die verwendet wurden, um eine Crash-Wiederherstellungsaufzeichnung der Änderungen zu führen.

Diese Spülung erfolgt in zwei Phasen:

  • Gepufferte write()s von schmutzigen shared_buffers Zu den Tabellen; und
  • fsync() der betroffenen Dateien, um sicherzustellen, dass die Änderungen wirklich die Festplatte treffen

Beides kann die E/A-Belastung der Festplatte erhöhen. Durch diese Schreibvorgänge verursachte Konflikte können das Lesen verlangsamen und das Löschen von WAL-Segmenten verlangsamen, das zum Festschreiben von Transaktionen erforderlich ist.

Es war eine langjährige Herausforderung, aber es wird schlimmer, wenn wir Systeme mit immer mehr RAM) sehen, damit sie mehr Daten puffern und länger brauchen, um sie auszuschreiben. Es gibt Diskussionen zwischen den Linux- und PostgreSQL-Communitys, wie im Moment damit umgegangen werden soll, wie in diesem LWN.net-Artikel beschrieben . (LWN.net kann diese großartige Arbeit nicht weiter schreiben, wenn die Leute sich nicht anmelden. Ich bin Abonnent und teile diesen Link, weil er nützlich und informativ ist. Bitte abonnieren Sie ihn, wenn Sie mehr davon sehen möchten.)

Das Wichtigste, was Sie tun können, um die Auswirkungen von Checkpoints im Moment zu verringern, ist die Verteilung der Checkpoint-Aktivität durch Erhöhen von checkpoint_completion_target, So dass bis zum Eintreffen des endgültigen Checkpoints mehr Daten ausgeschrieben wurden. Dies ist jedoch mit Kosten verbunden. Wenn Sie eine Seite (z. B.) zehnmal aktualisieren, wird sie möglicherweise mehrmals vor dem Prüfpunkt mit einem Ziel mit hoher Fertigstellung auf die Festplatte geschrieben, obwohl sie aus Sicherheitsgründen nur einmal ausgeschrieben werden musste. Ein höheres Abschlussziel sorgt für glattere E/A-Muster, aber insgesamt mehr E/A-Overhead.

Sie können Ihrem Betriebssystem auch mitteilen, dass es sofort mit dem Schreiben von Daten beginnen soll, wenn gepufferte Schreibvorgänge ausgeführt werden. Dies ist wie die Kernelseite der Einstellung checkpoint_completion_target Und hat einen ähnlichen Kompromiss. Siehe die Linux VM-Dokumentation , insbesondere dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.

32
Craig Ringer

Leeren der fehlerhaften Betriebssystem-Dateisystempuffer durch Überschreiten von dirty_bytes oder dirty_ratio ist eine Vordergrundblockierungsoperation!

Die Kernel-Tunables dirty_bytes, dirty_background_bytes, dirty_ratio, dirty_background_ratio und dirty_centisecs Steuern Sie das Leeren verschmutzter Betriebssystem-Dateisystempuffer auf die Festplatte. dirty_bytes ist der Schwellenwert in Bytes, dirty_ratio ist der Schwellenwert als Verhältnis des Gesamtspeichers. dirty_background_bytes und dirty_background_ratio sind ähnliche Schwellenwerte, aber das Löschen erfolgt im Hintergrund und blockiert andere Lese-/Schreibvorgänge erst, wenn es abgeschlossen ist. dirty_centisecs gibt an, wie viele Centisekunden vergehen können, bevor ein Flush eingeleitet wird.

Vor kurzem wurden die Standardeinstellungen für diese Tunables unter Linux gesenkt, da die Speichergröße für moderne Maschinen dramatisch zugenommen hat. Gerade Verhältnisse von 5 und 10% für dirty_background_ratio und dirty_ratio auf einem 256-GB-Computer kann ein E/A-System überfluten.

Tuning dirty_background_bytes oder dirty_background_ratio es ist schwierig, schmutzige Puffer im Hintergrund zu leeren. Glücklicherweise können Sie diese Einstellungen optimieren, ohne PostgreSQL oder den Host stoppen zu müssen, indem Sie neue Werte in die entsprechenden Dateien übertragen:

$ Sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

zum Beispiel, um die Anzahl der verschmutzten Bytes festzulegen, die eine Hintergrundspülung auslösen sollen. Wenn Sie eine batteriegepufferte, kondensatorgestützte oder Flash-Speicher-RAID-Karte verwenden (Sie tun möchten Ihre behalten Daten im Falle eines Absturzes, nicht wahr?) Beginnen Sie mit der Abstimmung von dirty_background_bytes bis 1/2 der Größe des Schreibcache-Puffers und dirty_bytes bis 3/4 dieser Größe. Überwachen Sie Ihr E/A-Profil mit iostats. Wenn weiterhin Latenzprobleme auftreten, bedeutet dies, dass die Schreiblast Ihrer Datenbank den Cache des Dateipuffers immer noch überlastet. Verringern Sie die Werte, bis sich die Latenz verbessert, oder erwägen Sie ein Upgrade Ihres E/A-Subsystems. FusionIO-Karten und SSDs sind zwei Möglichkeiten für einen extremen E/A-Durchsatz.

Viel Glück!

1
bobl