Die vier Reiter hinter tausenden Postgres-Ausfällen

Deine Reaktion:

Du betreibst eine Webanwendung, alles läuft – bis die Datenbank nicht mehr reagiert. Kein SELECT, kein INSERT. Server hängt, Fehlerlogs laufen über. Wer eine PostgreSQL-Instanz betreut, kennt diese Momente. Sie haben oft vier Ursachen. Der Entwickler von pgrust, einer Neuimplementierung von Postgres in Rust, hat diese Problembereiche analysiert. Er beschreibt, warum sie zu Ausfällen führen – und wie sein Ansatz helfen könnte. Schauen wir uns die vier Punkte an.

1. VACUUM und Transaction ID Wraparound – die stille Gefahr

Wenn du in Postgres eine Zeile löschst, wird sie nicht sofort physisch entfernt. Postgres markiert sie als gelöscht – das ermöglicht Rollbacks. Die Bereinigung übernimmt ein Hintergrundprozess namens VACUUM. Er liest alle Daten und entfernt die markierten Zeilen. Das klingt harmlos, birgt aber zwei Risiken. Erstens: VACUUM frisst I/O. Es konkurriert mit deinen Abfragen um die Festplattenbandbreite. Stell dir vor, du liest ein Buch, während jemand neben dir Seiten herausreißt – so ähnlich fühlt es sich für die Datenbank an. Du musst VACUUM richtig einstellen: aggressiv genug, um mit gelöschten Zeilen Schritt zu halten, aber nicht so aggressiv, dass es Queries ausbremst. Eine knifflige Balance, besonders ohne dedizierten Datenbank-Admin.

Das zweite Problem ist tückischer: Transaction ID Wraparound. Postgres vergibt pro Transaktion eine 32-Bit-ID – maximal vier Milliarden IDs. Sind alle verbraucht, müssen sie wiederverwendet werden. VACUUM markiert alte IDs, damit sie sicher recycelt werden. Hinkt VACUUM hinterher, schaltet Postgres die Datenbank komplett ab – sonst könnten Daten korrupt werden. Der Autor schätzt, dass dieser Mechanismus weltweit für tausende, wenn nicht zehntausende Ausfälle verantwortlich ist. pgrust plant zwei Lösungen: 64-Bit-Transaktions-IDs, die zwar Overhead pro Zeile bedeuten, aber den Wraparound praktisch auf unbestimmte Zeit verschieben. Außerdem wird eine Architektur ohne VACUUM diskutiert – ähnlich dem Undo-Log von Oracle. Der Ansatz ist vielversprechend, erfordert aber grundlegende Änderungen.

2. Connection Limits und Query Parallelism – wenn die Türen zu bleiben

Jede Postgres-Instanz hat eine Konfigurationsvariable für die maximale Anzahl gleichzeitiger Verbindungen. Wenn mehr Clients versuchen, sich zu verbinden, werden sie abgewiesen – die Datenbank ist nicht erreichbar. Simpel, aber die Falle lauert im Detail: Änderungen an diesem Grenzwert erfordern einen Neustart. Wer den Wert zu niedrig ansetzt, steht im Regen. Viele nutzen PgBouncer, einen Verbindungspooler, der das Problem mildert, aber nicht beseitigt. Warum ein Grenzwert? Der Grund liegt in der Prozess-Architektur von Postgres. Für jede neue Verbindung erzeugt Postgres einen Betriebssystem-Prozess. Prozesse sind teuer – sie brauchen CPU, Speicher und Zeit zum Starten. Das schränkt nicht nur die Parallelisierung zwischen Abfragen ein, sondern auch innerhalb einer einzelnen Abfrage. Denn wenn Postgres eine aufwendige Query parallel ausführen will, startet es ebenfalls mehrere Prozesse. Wegen der hohen Kosten tut es das nur bei wirklich langlaufenden Abfragen.

Seit Jahren wird über eine Umstellung auf ein Thread-Modell diskutiert, aber die Änderung ist so tiefgreifend, dass kaum jemand sie wagt. pgrust wurde von Anfang an mit Threads konzipiert. Der Autor betont, dass die Prozess-Architektur der Sicherheit dient: Prozesse sind stärker isoliert als Threads. Ein Fehler in einem Prozess reißt die anderen nicht mit. pgrust setzt auf die Speichersicherheitsgarantien von Rust zur Compile-Zeit, sodass diese Isolation nicht nötig ist. Das verspricht schnellere Verbindungsaufnahmen und effizientere Parallelisierung – ohne lästige Grenzwerte und Umwege über PgBouncer.

3. Bad Query Plans – wenn der Optimierer daneben liegt

Postgres besitzt einen Planer für Abfragen. Er analysiert die SQL-Query, zieht Statistiken über die Tabellen heran und wählt aus Dutzenden Algorithmen den vermeintlich schnellsten aus. Meist funktioniert das gut. Wenn der Planer daneben liegt, dann richtig. Der Unterschied zwischen einem guten und einem schlechten Ausführungsplan kann den Faktor 60.000 ausmachen: eine Query, die normalerweise 10 Millisekunden braucht, läuft plötzlich 10 Minuten. Das ist bekannt. Noch ärgerlicher: Postgres bietet kaum Möglichkeiten, den Planer direkt zu lenken. Während andere Datenbanken wie MySQL Planner Hints unterstützen, mit denen du für einzelne Queries den Algorithmus vorgeben kannst, fehlt diese Funktion in Postgres komplett. Die einzige Stellschraube ist das globale Abschalten bestimmter Algorithmen – ein grobes Werkzeug.

Der Autor von pgrust berichtet von einem früheren Arbeitgeber, bei dem sie in der gesamten Datenbank Nested-Loop-Joins deaktivieren mussten, weil Postgres sie ständig nutzte und alle Queries ausbremste. Grund war oft der Umgang mit JSON-Daten. Für pgrust schwebt dem Entwickler ein adaptiver Query Planer vor, der ständig die Ausführungszeiten überwacht. Wenn eine Query, die normalerweise 10ms braucht, plötzlich 10 Sekunden benötigt, soll pgrust automatisch erkennen, ob der Plan gewechselt hat oder die Statistiken veraltet sind, und ohne menschliches Eingreifen korrigieren. Klingt futuristisch, aber der Autor ist optimistisch, dass dies realisierbar ist – es fehlt nur die konkrete Umsetzung.

4. JSON – scheinbarer Segen mit versteckten Fallstricken

Postgres liebt und hasst JSON. Es ist nützlich, um unstrukturierte Daten zu speichern und flexibel abzufragen. Aber die Schattenseiten sind massiv. Das größte Problem: Postgres sammelt für JSON-Spalten keine vernünftigen Statistiken. Für normale Datentypen wie Integer oder Text erhebt es Histogramme, häufigste Werte und mehr. Bei JSON schätzt der Planer pauschal, dass ein Filter auf eine JSON-Eigenschaft nur 0,1 % der Zeilen trifft – ein fixer Wert, völlig unabhängig von den tatsächlichen Daten. Der tatsächliche Anteil kann bei 80 % oder bei 0,0001 % liegen. Diese Fehleinschätzung führt zu schlechten Abfrageplänen. Wer mit großen JSON-Spalten gearbeitet hat, kennt das Gefühl, wenn Abfragen plötzlich explodieren.

Hinzu kommt, dass Postgres JSON nicht komprimiert. Werden in vielen Zeilen die gleichen Schlüssel und Werte verwendet, werden sie jedes Mal neu gespeichert. Das bläht die Datenbank auf. Der Autor von pgrust sieht zwei Ansatzpunkte: echte Statistiken für JSON-Spalten – das würde nach seiner Einschätzung 80 % der JSON-bedingten Probleme lindern. Es existieren bereits Patches, die in diese Richtung gehen; er möchte einen zur Serienreife bringen. Zweitens eine Wörterbuchkomprimierung (Dictionary Compression), um sich wiederholende JSON-Inhalte platzsparender abzulegen. Das könnte den Speicherverbrauch drastisch reduzieren und die I/O-Last verringern.

Was bleibt – und was pgrust konkret bedeutet

Die vier Punkte – VACUUM/Wraparound, Connection Limits, schlechte Query-Pläne und JSON – sind keine akademischen Probleme. Sie verursachen täglich Ausfälle in tausenden Unternehmen. Der Entwickler von pgrust hat sich vorgenommen, diese Schwachstellen mit einem technisch durchdachten Neuanfang zu adressieren. Der Fokus des Projekts liegt auf zwei Dingen: erstens Kompatibilität mit PostgreSQL – pgrust besteht bereits 96 % der offiziellen Regressionstests. Zweitens Stabilität und Fehlerbereinigung, damit die Datenbank ernsthaft eingesetzt werden kann. Erst danach sollen die architektonischen Verbesserungen kommen, beginnend mit den 64-Bit-Transaktions-IDs.

Für dich als Betreiber einer Postgres-Installation bedeutet das: Solange pgrust nicht produktionsreif ist, solltest du die genannten Fallstricke aktiv managen. Überwache deine VACUUM-Aktivitäten, setze PgBouncer ein, um Connection Limits zu puffern, analysiere regelmäßig deine Abfragepläne und meide JSON, wo möglich, oder schaffe dir Monitoring für plötzliche Performance-Einbrüche. Die Arbeit an pgrust zeigt, dass die Probleme erkannt sind und Lösungen existieren.

Quelle: malisper.me

Deine Reaktion:
Artikel teilen:
Sebastian Krötzsch
Autor

Sebastian Krötzsch

Sebastian Krötzsch schreibt auf sebask.de über Künstliche Intelligenz, Automatisierung, digitale Systeme und die Frage, was davon im Alltag wirklich nützlich ist. Ohne Buzzword-Nebel, dafür mit klarem Blick auf Praxis, Tools und echte Wirkung.