Einer meiner PostgreSQL-Server hostet mehrere (1-3) Datenbanken, die einen konstanten Datenstrom erhalten. Die Daten sind nicht besonders strukturiert, sondern entsprechen der aktuellen Zeit und einer Vielzahl von beobachteten Daten für diesen bestimmten Zeitpunkt. Die Datenrate ist ziemlich hoch; Für eine Datenbank sind es ungefähr ein Gigabyte pro Tag, für eine andere etwa ein Zehntel. Ich erwarte keine Erhöhung dieser Rate. Die Leseleistung hat eine viel niedrigere Priorität und ist derzeit akzeptabel.
In den Protokollen habe ich diese Nachricht:
LOG: checkpoints are occurring too frequently (15 seconds apart)
HINT: Consider increasing the configuration parameter "checkpoint_segments".
Dieser Wert ist derzeit auf 16 eingestellt, was mit freundlicher Genehmigung von ist pgtune
.
Welche Einstellungen sollte ich berücksichtigen, um die Schreibleistung zu verbessern? Ich würde es vorziehen, so viel Sicherheit wie möglich zu haben. In Anbetracht des eingehenden Datenvolumens könnte ich akzeptieren, dass bei einem Fehler einige aktuelle Daten verloren gehen, solange der Großteil der Daten intakt ist.
Bearbeiten: Ich verwende derzeit PostgreSQL 9.0, plane jedoch ein Upgrade auf 9.1. Ich gebe die Hardwaredetails nicht bekannt, da ich zwar deren Bedeutung anerkenne, diese Optimierung jedoch letztendlich auf mehreren Computern mit sehr unterschiedlicher Hardware durchführen muss. Wenn die Hardware für die Antwort wesentlich ist, geben Sie mir bitte die allgemeinen Informationen, damit ich die Antwort auf Maschinen mit unterschiedlichen Hardwarekonfigurationen anwenden kann.
quelle
checkpoint_segments
wie empfohlen erhöht ? Was ist passiert?Antworten:
1 Gigabyte pro Tag ist keine so hohe Schreiblast. Verteilen Sie sich über den Tag, das sind ungefähr 50 KByte pro Sekunde. Ein langsamer USB-Stick könnte damit umgehen. Ich gehe aber davon aus, dass es platzt. Erhöhen Sie die Checkpoint-Segmente, wie ein Pferd mit keinem Namen vorschlägt. 100 oder so ist nicht ungewöhnlich.
Erhöhen Sie dann Ihren Wert
checkpoint_timeout
auf 1 Stunde und dencheckpoint_completion_target
Wert auf 1,0 (100%). Das Abschlussziel teilt PostgreSQL mit, wie aggressiv das Schreiben im Hintergrund erfolgen soll, damit es zu x% abgeschlossen ist, bevor ein Prüfpunkt ausgeführt wird. Dadurch werden alle Daten auf einmal aus dem WAL ausgeschrieben, und das System wird beim Durchforsten verlangsamt.Der Grund, warum Sie diesen Wert normalerweise nicht auf 100% setzen, ist, dass häufig mehr als einmal in denselben Block geschrieben wird. Indem Sie WAL-Schreibvorgänge in den Hauptspeicher verzögern, verhindern Sie, dass derselbe Block ohne Grund zweimal geschrieben wird.
Wenn es unwahrscheinlich ist, dass Sie mehr als einmal in denselben Block schreiben, bevor Ihr Timeout auftritt, dh wenn Sie nur Einfügen ausführen, ist es sinnvoll, ihn auf 0,9 oder so hoch zu setzen. Das Schlimmste, was passieren kann, ist, dass Sie ein wenig häufiger schreiben, als Sie es ansonsten benötigen. Die Auswirkungen auf Checkpoints werden jedoch erheblich reduziert.
quelle
In einem sehr "schreiblastigen" System sind Sie wahrscheinlich an die Rate gebunden, mit der WAL während der Spitzenaktivität geschrieben werden kann.
Wenn Sie wirklich „akzeptieren einige aktuelle Daten in einem Ausfall zu verlieren“ können Sie ausschalten synchron begehen , die:
Wenn Sie in der Lage sind, Ihre Hardware zu ändern, können Sie für die Optimierung der Schreibvorgänge Folgendes in Betracht ziehen:
--bearbeiten
Ausgehend von Ihrem Kommentar zu @ Scotts hervorragender Antwort : "Das Schreibvolumen ist tatsächlich nahezu gleichmäßig" und der implizierten Datenrate von "50 KByte pro Sekunde" bezweifle ich, dass Sie etwas unternehmen müssen, das den Verlust von Daten gefährdet. Vielleicht ist es hilfreich zu wissen, auf welche anderen Konfigurationsparameter Sie eingestellt sind.
quelle
Sie können auch die Häufigkeit / Größe Ihrer Commits überprüfen: Ich bin kürzlich auf ein Problem gestoßen, bei dem ich versucht habe,> 1 Million Datensätze in einer einzelnen Transaktion zu aktualisieren. Ich habe ähnliche Protokollmeldungen wie bei OP erhalten, aber die Transaktion konnte auch nach mehreren Stunden nicht abgeschlossen werden. Als ich den Schreibvorgang in mehrere kleinere Transaktionen aufteilte (etwa 10.000 Datensätze), ging die Gesamtzeit auf etwa 15 Minuten zurück.
Was ich denke, ist, dass Postgres so viel Zeit damit verbracht hat, die Protokolle zu schreiben, dass checkpoint_timeout verstrichen ist, bevor es wesentliche Fortschritte beim Speichern der Aufzeichnungen machen konnte. Ich bin mir nicht sicher, ob diese Erklärung zutrifft. Ich bekomme immer noch die Warnungen, aber alle Schreibvorgänge werden schließlich verarbeitet. Ich brauchte (und fand) jedoch eine programmatische Problemumgehung und keine, die eine Neukonfiguration der Datenbank erforderte.
Siehe auch http://www.postgresql.org/docs/9.3/static/wal-configuration.html
quelle