Optimierung von PostgreSQL für transiente Daten

8

Ich habe mehrere Tabellen mit jeweils 100-300 Spalten mit ganzzahligen Typen, die sehr flüchtige Daten enthalten. Die Datensätze werden mit einem oder zwei Primärschlüsseln verschlüsselt. Bei einer Aktualisierung wird der gesamte Datensatz gelöscht und neue Daten in eine Transaktion eingefügt. Die Datensatzgröße beträgt normalerweise einige hundert Zeilen, kann jedoch im Extremfall bis zu mehreren tausend Zeilen betragen. Die Aktualisierung erfolgt einmal pro Sekunde, und Dataset-Aktualisierungen für verschiedene Schlüssel werden normalerweise getrennt, sodass das Löschen und Neuerstellen der Tabelle nicht möglich ist.

Wie stelle ich Postgres auf diese Last ein? Ich kann die neueste und beste Version verwenden, wenn das einen Unterschied macht.

Alex Tokarev
quelle

Antworten:

7

Abhängig davon, wie viele verschiedene Datensätze vorhanden sind, besteht eine Option darin, die Tabellen pro Datensatz zu partitionieren.

Wenn ein Datensatz aktualisiert wird, werden BEGINeine neue Transaktion, TRUNCATEdie Tabelle, COPYdie neuen Daten darin und COMMIT. PostgreSQL hat eine Optimierung , wo COPYin eine Tabelle , die ing gewesen TRUNCATEd in derselben Transaktion kann noch viel weniger I / O , wenn Sie verwenden wal_level = minimal(Standardeinstellung).

Wenn Sie nicht partitionieren und abschneiden können (z. B. wenn Sie mit Zehntausenden oder Hunderttausenden von Datensätzen arbeiten, in denen es einfach zu viele Tabellen gibt), möchten Sie stattdessen das Autovakuum hochdrehen, um so viel wie möglich auszuführen Stellen Sie sicher, dass Sie gute Indizes für alles haben, was Sie basierend auf löschen, und seien Sie auf eine etwas normale Leistung vorbereitet.

Wenn Sie keine Absturzsicherheit benötigen - es macht Ihnen nichts aus, dass Ihre Tabellen nach einem Systemabsturz leer sind -, können Sie Ihre Tabellen auch als erstellen UNLOGGED, wodurch Sie eine enorme Menge an E / A-Kosten sparen.

Wenn es Ihnen nichts ausmacht, nach einem Systemabsturz das gesamte Setup aus einem Backup wiederherzustellen, können Sie einen Schritt weiter gehen und auch festlegen fsync=off, was PostgreSQL im Grunde sagt: "Kümmern Sie sich nicht um die Absturzsicherheit, ich habe gute Backups und ich ziehe nicht an." Es ist mir egal, ob meine Daten nach einem Absturz dauerhaft und vollständig nicht wiederherstellbar sind, und ich bin froh, sie erneut zu verwenden, initdbbevor ich meine Datenbank wieder verwenden kann. "

Ich habe in einem ähnlichen Thread über Stack Overflow mehr darüber geschrieben, wie man PostgreSQL für schnelle Tests optimiert . Dies erwähnt die Optimierung des Host-Betriebssystems und die Trennung von WAL auf eine andere Festplatte, wenn Sie keine unloggedTabellen, Checkpointer-Anpassungen usw. verwenden.

Es gibt auch einige Informationen in den Pg-Dokumenten für schnelles Laden von Daten und nicht dauerhafte Einstellungen .

Craig Ringer
quelle
Vielen Dank für den Partitionstipp, ich habe in diesem Fall nie darüber nachgedacht, sie zu verwenden. Was nicht protokollierte Tabellen betrifft - meinen Sie, dass sie nach einem Systemabsturz standardmäßig leer sind? Es macht keinen Unterschied, ich bin nur neugierig.
Alex Tokarev
1
@AlexTokarev Das stimmt; Nachdem PostgreSQL unsauber heruntergefahren wurde (Postmaster oder ein Backend segfaults, das System wird plötzlich aus- und wieder eingeschaltet, das Backend wird bearbeitet SIGKILLusw.), können alle UNLOGGEDTabellen TRUNCATEd sein, sodass sie beim Start leer sind. Sie werden nach einem sauberen Herunterfahren und Neustart nicht abgeschnitten, aber Sie sollten sich nicht darauf verlassen, dass sie dauerhaft sind.
Craig Ringer
Danke für die Erklärung. Ich benötige keine Datensicherheit für die betreffenden Tabellen, die darin enthaltenen Daten sind vorübergehend und werden jede Sekunde von der Quelle aktualisiert. Das Deaktivieren von fsync ist jedoch keine Option, da es andere, traditionellere Tabellen im selben Schema gibt, die sicher und wiederherstellbar sein müssen. Die UNLOGGEDOption pro Tisch zu haben ist einfach großartig.
Alex Tokarev
Ich schaue auf das Partitionierungsdokument und es sieht so aus, als ob es eine (fast) perfekte Lösung für das Problem sein könnte. Eine Frage: Wenn ich eine übergeordnete Tabelle für Schema- und untergeordnete Tabellen haben möchte, in der die Daten gespeichert sind, werde ich die Daten aus der übergeordneten Tabelle abfragen, oder? Wenn eine untergeordnete Tabelle für diesen Bereich vorhanden ist, gibt die Abfrage diese zurück. Wenn nicht, wird ein leeres Dataset zurückgegeben. In diesem Fall kann ich sogar untergeordnete Tabellen für jeden neuen Datenstapel löschen und neu erstellen. Was ist unter den gegebenen Umständen effektiver TRUNCATEoder in welcher DROP/CREATE TABLEReihenfolge?
Alex Tokarev
@AlexTokarev Ich würde Ihnen TRUNCATEpersönlich empfehlen . DDL-Abwanderung hat ihre eigenen Kosten. Da Sie häufig Änderungen mit einem so hohen Wert vornehmen, ist es sehr wichtig sicherzustellen, dass Sie die Aggressivität von Autovacuum auf pg_catalog.pg_classund anderen Systemtabellen erhöhen, die unter dieser Arbeitslast möglicherweise aufblähen.
Craig Ringer