Was passiert im PostgreSQL-Checkpoint?

22

Hier ist ein Teil meines Checkpoint-Logs:

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 sehen eine sehr große Anzahl von normalerweise kurzen Abfragen, 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?

Konrad Garus
quelle

Antworten:

32

Während des Vorgangs zeichnet PostgreSQL Änderungen an Transaktionsprotokolldateien auf, überträgt diese jedoch nicht sofort in die eigentlichen Datenbanktabellen. Normalerweise werden die Änderungen nur im Arbeitsspeicher gespeichert und auf Anforderung aus dem Arbeitsspeicher zurückgegeben, es sei denn, der Arbeitsspeicher wird voll und muss sie auslesen.

Dies bedeutet, dass bei einem Absturz die Festplattentabellen nicht mehr aktuell sind. Es muss die Transaktionsprotokolle erneut abspielen und die Änderungen auf die Festplattentabellen anwenden, bevor es wieder gestartet werden kann. Bei einer großen, ausgelasteten Datenbank kann dies 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. Alle ausstehenden Änderungen werden auf die Festplatte geschrieben, und die Transaktionsprotokolle, die zum Aufzeichnen der Änderungen zur Wiederherstellung nach einem Absturz verwendet wurden, werden wiederhergestellt.

Diese Spülung erfolgt in zwei Phasen:

  • Gepufferte write()s dreckig shared_buffersauf den Tischen; und
  • fsync() der betroffenen Dateien, um sicherzustellen, dass die Änderungen wirklich auf die Festplatte treffen

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

Es ist eine langjährige Herausforderung, aber es wird immer schlimmer, wenn wir Systeme mit immer mehr RAM sehen, damit sie mehr Daten puffern und länger brauchen, um sie zu schreiben. Die Linux- und PostgreSQL-Community diskutieren derzeit, wie sie damit umgehen sollen, wie in diesem Artikel von LWN.net beschrieben . (LWN.net wird nicht in der Lage sein, diese großartige Arbeit zu schreiben, wenn die Leute nicht abonnieren. Ich bin Abonnent und teile diesen Link, weil er nützlich und informativ ist. Bitte abonnieren Sie, wenn Sie mehr davon sehen möchten so etwas.)

Das Wichtigste, was Sie tun können, um die Auswirkung von Checkpoints im Moment zu verringern, ist, die Checkpoint-Aktivität zu verteilen, indem Sie sie checkpoint_completion_targetso erhöhen , dass zum Zeitpunkt des Eintreffens des endgültigen Checkpoints mehr Daten ausgeschrieben werden. Dies ist jedoch mit Kosten verbunden. Wenn Sie eine Seite (beispielsweise) zehnmal aktualisieren, wird sie möglicherweise mehrmals vor dem Checkpoint mit einem hohen Abschlussziel auf die Festplatte geschrieben, obwohl sie aus Gründen der Absturzsicherheit nur einmal auf die Festplatte geschrieben werden muss. Ein höheres Abschlussziel sorgt für glattere E / A-Muster, aber insgesamt mehr E / A-Aufwand.

Sie können auch Ihr Betriebssystem anweisen, sofort mit dem Schreiben von Daten zu beginnen, wenn es gepufferte Schreibvorgänge erhält. Dies ist wie die Kernel-Seite des Einstellens checkpoint_completion_targetund hat einen ähnlichen Kompromiss. Siehe die Linux vm Dokumentation , insbesondere dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.

Craig Ringer
quelle
Das Schreiben ist über einen langen Zeitraum verteilt und ich glaube nicht, dass es Probleme verursacht. Was ist mit der Synchronisierung, ist es zufällig eine Art Stop-the-World-Operation?
Konrad Garus
@KonradGarus Die Synchronisierung sollte kein weltweiter Vorgang sein, ist es aber häufig. Lesen Sie den Artikel, den ich oben verlinkt habe, es ist eine sehr aktuelle und nützliche Zusammenfassung der Probleme, wenn auch aus einer ziemlich technischen Sicht. Die Kurzversion lautet "fsync () unter Linux führt dazu, dass die Leistung von E / A, die gleichzeitig mit fsync () ausgeführt werden, vollständig beeinträchtigt wird". Sie können dies mit den oben aufgeführten Optimierungsoptionen abschwächen, um die Menge zu verringern, die von einem fsync gelöscht werden muss.
Craig Ringer
1

Spülen der schmutzigen OS - Dateisystempuffer verursacht durch Überschreiten dirty_bytesoder dirty_ratio wird ein Vordergrundsperrbetrieb!

Das Kernel - tunables dirty_bytes, dirty_background_bytes, dirty_ratio, dirty_background_ratiound dirty_centisecsSteuer Spülen von schmutzigen OS - Dateisystem - Puffern auf der Festplatte. dirty_bytesist die Schwelle in Bytes, dirty_ratioist die Schwelle als Verhältnis des gesamten Speichers. dirty_background_bytesund dirty_background_ratiosind ähnliche Schwellenwerte, aber das Leeren erfolgt im Hintergrund und blockiert andere Lese- / Schreibvorgänge erst, wenn es abgeschlossen ist. dirty_centisecsist, wie viele Zentisekunden vergehen können, bevor ein Flush ausgelöst wird.

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

Das Einstellen dirty_background_bytesoder dirty_background_ratioLöschen von verschmutzten Puffern im Hintergrund ist schwierig. Glücklicherweise können Sie diese Einstellungen anpassen, ohne PostgreSQL oder den Host anhalten zu müssen, indem Sie neue Werte in die entsprechenden Dateien einfügen:

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

Zum Beispiel, um die Anzahl der verschmutzten Bytes festzulegen, die eine Hintergrundbereinigung auslösen. Wenn Sie einen batteriegepufferten verwenden, Kondensator-backed, oder Flash - Speicher - RAID - Karte (Sie tun möchten , dass Ihre Daten im Falle eines Crashs zu halten, nicht wahr?) Starten durch Abstimmung dirty_background_bytesauf 1/2 der Schreib - Cache - Puffergröße und dirty_byteszu 3/4 dieser Größe. Überwachen Sie Ihr E / A-Profil mit iostats, und wenn weiterhin Latenzprobleme auftreten, bedeutet dies, dass die Schreiblast Ihrer Datenbank die Cache-Leerungen des Dateipuffers immer noch überfordert. Verringern Sie die Werte, bis sich die Latenz verbessert, oder überlegen Sie, Ihr E / A-Subsystem zu aktualisieren. FusionIO-Karten und SSDs sind zwei Möglichkeiten für extremen E / A-Durchsatz.

Viel Glück!

Bobl
quelle
Ihr Kommentar zu "schmutzigen" Daten ist ein relevanter Punkt für die Langsamkeit. Grundsätzlich gilt: Je größer das Dirty-Verhältnis, desto mehr Puffer wird für Dirty-Daten reserviert, bevor das Entleeren einsetzt. Wenn Sie also die Verzögerungen beim Entleeren minimieren, müssen Sie den Dirty-Puffer vergrößern oder die Zeit verlängern, in der die Dirty-Daten im Speicher verbleiben können.
Peter Teoh