PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Messen von PostgreSQL Checkpoint-Statistiken

Checkpoints können eine große Belastung für schreibintensive PostgreSQL-Installationen sein. Der erste Schritt zum Identifizieren von Problemen in diesem Bereich besteht darin, zu überwachen, wie oft sie auftreten, was erst kürzlich um eine benutzerfreundlichere Oberfläche in der Datenbank ergänzt wurde.

Prüfpunkte sind regelmäßige Wartungsvorgänge, die die Datenbank durchführt, um sicherzustellen, dass alles, was sie im Speicher zwischengespeichert hat, mit der Festplatte synchronisiert wurde. Die Idee ist, dass Sie sich, sobald Sie eine fertig gestellt haben, keine Gedanken mehr über ältere Einträge machen müssen, die in das Write-Ahead-Protokoll der Datenbank aufgenommen wurden. Das bedeutet weniger Zeit für die Wiederherstellung nach einem Absturz.
Das Problem mit Checkpoints ist, dass sie sehr intensiv sein können, denn um einen zu vervollständigen, muss jedes einzelne Bit der geänderten Daten im Puffercache der Datenbank auf die Festplatte geschrieben werden. PostgreSQL 8.3 wurde eine Reihe von Funktionen hinzugefügt, die es Ihnen ermöglichen, den Checkpoint-Overhead besser zu überwachen und ihn zu senken, indem Sie die Aktivität über einen längeren Zeitraum verteilen. Ich habe einen langen Artikel über diese Änderungen mit dem Titel "Checkpoints and the Background Writer" geschrieben, der aufzeigt, was sich geändert hat, aber es ist ziemlich trocken zu lesen.
Was Sie wahrscheinlich wissen möchten, ist, wie Sie Checkpoints in Ihrem Produktionssystem überwachen und wie Sie dies feststellen können wenn sie zu oft vorkommen. Auch wenn sich die Dinge verbessert haben, sind „Checkpoint-Spikes“, bei denen die Festplatten-I/O sehr stark wird, auch in aktuellen PostgreSQL-Versionen immer noch möglich. Und es hilft nicht, dass die Standardkonfiguration eher auf sehr wenig Speicherplatz und eine schnelle Wiederherstellung nach einem Absturz als auf Leistung ausgelegt ist. Der checkpoint_segments-Parameter, der eine Eingabe dafür ist, wie oft ein Checkpoint auftritt, ist standardmäßig auf 3 eingestellt, was einen Checkpoint nach nur 48 MB an Schreibvorgängen erzwingt.
Sie können die Checkpoint-Häufigkeit auf zwei Arten herausfinden. Sie können log_checkpoints aktivieren und beobachten, was in den Protokollen passiert. Sie können auch die pg_stat_bgwriter-Ansicht verwenden, die eine Zählung jeder der beiden Quellen für Checkpoints (verstrichene Zeit und aufgetretene Schreibvorgänge) sowie Statistiken darüber angibt, wie viel Arbeit sie geleistet haben.
Das Hauptproblem dabei, dies zu vereinfachen tun ist, dass es bis vor kurzem unmöglich war, die Zähler innerhalb von pg_stat_bgwriter zurückzusetzen. Das heißt, Sie müssen einen Schnappschuss mit einem Zeitstempel darauf machen, eine Weile warten, einen weiteren Schnappschuss machen und dann alle Werte subtrahieren, um nützliche Statistiken aus den Daten abzuleiten. Das ist mühsam.
So mühsam genug, dass ich einen Patch geschrieben habe, um es einfacher zu machen. Mit der aktuellen Entwicklungsversion der Datenbank können Sie jetzt pg_stat_reset_shared(‚bgwriter‘) aufrufen und all diese Werte wieder auf 0 zurücksetzen. Dies ermöglicht es, einer Praxis zu folgen, die früher bei PostgreSQL üblich war. Vor 8.3 gab es einen Parameter namens stats_reset_on_server_start, den Sie aktivieren konnten. Dadurch werden alle internen Statistiken des Servers bei jedem Start zurückgesetzt. Das bedeutete, dass Sie die praktische Funktion pg_postmaster_start_time() aufrufen, mit der aktuellen Zeit vergleichen und immer eine genaue Zählung in Bezug auf Operationen/Sekunde jeder auf dem System verfügbaren Statistik haben konnten.
Es ist immer noch nicht automatisch, aber jetzt dass das Zurücksetzen dieser gemeinsamen Teile möglich ist, können Sie es selbst tun. Der erste Schlüssel besteht darin, das Löschen von Statistiken in Ihre Server-Startsequenz zu integrieren. Ein Skript wie dieses wird funktionieren:


pg_ctl start -l $PGLOG -w
psql -c "select pg_stat_reset();"
psql -c "select pg_stat_reset_shared('bgwriter');"

Beachten Sie dort das »-w« beim Startbefehl – ​​das lässt pg_ctl warten, bis der Server mit dem Start fertig ist, bevor er zurückkehrt, was wichtig ist, wenn Sie sofort eine Anweisung dagegen ausführen wollen.
Falls Sie das getan haben das, und Ihre Server-Startzeit ist im Wesentlichen dieselbe wie zu der Zeit, als der Hintergrundschreiber mit der Sammlung von Statistiken begann, können Sie jetzt diese lustige Abfrage verwenden:


SELECT
total_checkpoints,
seconds_since_start / total_checkpoints / 60 AS minutes_between_checkpoints
FROM
(SELECT
EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time())) AS seconds_since_start,
(checkpoints_timed+checkpoints_req) AS total_checkpoints
FROM pg_stat_bgwriter
) AS sub;

Und erhalten Sie einen einfachen Bericht darüber, wie oft Checkpoints auf Ihrem System stattfinden. Die Ausgabe sieht so aus:


total_checkpoints           | 9
minutes_between_checkpoints | 3.82999310740741

Was Sie mit diesen Informationen tun, ist, auf das durchschnittliche Zeitintervall zu starren und zu sehen, ob es zu schnell erscheint. Normalerweise möchten Sie, dass ein Checkpoint nicht öfter als alle fünf Minuten stattfindet, und auf einem ausgelasteten System müssen Sie es möglicherweise auf zehn Minuten oder länger verschieben, um eine Hoffnung zu haben, Schritt zu halten. Bei diesem Beispiel ist alle 3,8 Minuten wahrscheinlich zu schnell – dies ist ein System, das höhere Werte für checkpoint_segments benötigt.
Wenn Sie diese Technik zum Messen des Checkpoint-Intervalls verwenden, wissen Sie, ob Sie die Parameter checkpoint_segments und checkpoint_timeout der Reihe nach erhöhen müssen um dieses Ziel zu erreichen. Sie können die Zahlen jetzt manuell berechnen, und sobald 9.0 ausgeliefert wird, können Sie es vollständig automatisch machen – solange es Ihnen nichts ausmacht, dass Ihre Statistiken bei jedem Neustart des Servers verschwinden.
Es gibt einige andere interessante Möglichkeiten um die Daten zu analysieren, die der Hintergrundschreiber in pg_stat_bgwriter bereitstellt, aber ich werde heute nicht alle meine Tricks verraten.