Transaction log defekt

Hallo Zusammen,
ich bin neu im Thema Postgres.

Unser Produktive System läuft in Kubernetes und viele Pods nutzen verschiedene Tabellen in einer Postgressdatenbank Version 11. Gelegentlich kommt es dazu, dass Postgres nicht mehr läuft bis wir den Transactionlog manuell gelöscht haben.

Meine Frage:
Wie kriegt man den Transactionlog am besten kaput?
Habt ihr Tipps? Was sollte man normalerweise vermeiden?
Gibt mir gerne schlechte Beispiele.

Mein aktueller Status.
Ich habe einen Test gebaut der folgendes tut.
a) Datenbank öffnen
b) Transaktion starten
c) Datenbankoperation ausführen
d) - ReadLine - damit der Prozess anhält.
Das wird 100 mal wiederholt.
e) 100 Client Prozesse killen, Postgress Docker killen (dann wird a bis d wiederholt und anders herum gekillt)
f) Resultat ? Datenbank noch mit den üblichen Tools erreichbar -> Ja

Ich habe auf meinen Rechner Docker Desktop und darin Postgress 11 am start.
Ich bin davon ausgegangen das ich den Fehler nachstellen kann, wenn ich die Clienten oder Postgress während einer Transaction vor dem Commit abschieße / kille.
Aber erstaunlicherweise bekomme ich die Datenbank / Transactionlog nicht kaputt und alles was ich bisher ausprobiert habe funktioniert in meiner Testumgebung richtig gut.

Ich würde mich sehr über Tipps zum schrotten des Postgres feuen.
VG Ben3D

Mehr Details und Files zum nachstellen in meinen Git

Bitte WAS?

Leg es auf NFS, das lügt manchmal. Oder, noch besser: auf eine RAM-Disk. Aber hey: warum willst Du Deine Daten überhaupt schrotten? Für sowas wurde MySQL erfunden…

Und jetzt ernsthaft: was passiert, was macht ihr genau, was wollt ihr erreichen?

Das Write-Ahead-Log (WAL) soll ja genau die von Dir beschriebene Situation absichern: wenn der Rechner einfach abstürzt oder der Strom ausfällt, dürfen keine Daten verloren gehen die bereits mit COMMIT geschrieben wurden.

Einen Client vor einem COMMIT zu killen, interessiert die Datenbank überhaupt nicht. Abschießen des Postgres Prozesses (was letzendlich sowas wie ein Stromausfall wäre) gehört auch zu den Szenarien die durch das WAL abgesichert werden.

Wogegen das System wenig machen kann sind Fehler im Dateisystem (z.B. Festplattenfehler). Das könntest Du simulieren indem Du z.B. eine (oder alle) WAL Dateien mit Zufallswerten überschreibst. Oder die Dateien leerst, so dass sie die Länge 0 haben.

Hallo Akretschmer,
Danke für deinen Hinweis. Ich möchte die Daten eigendlich nicht schrotten, sondern nur den Fehler den Wir haben nachstellen. Das mit dem NFS und dem RAM-Disk ist einer guter Hinweis.
Vielen Dank.
Ben

Hallo castorp,
Super, so etwas hatte ich bereits vermutet. Danke das Du mir auf den richtigen Pfad geholfen hast.
VG Ben

Super, wie ich gerade erfahren habe, hat das genau den Fehler verursacht, den wir gesucht haben. Nochmal danke.

Der Fehler war.
“PANIC: could not locate a valid checkpoint record”

VG Ben

Ich hätte zu dem Thema auch noch weitere Fragen. Gehen wir mal davon aus, dass aus irgendeinem Grund das WriteAheadLog korrumpiert wurde. Das verhalten bei mir ist dann so

  • Docker-Container Startet
  • Im log steht "PANIC: could not locate a valid checkpoint record
  • Docker-Container Stoppt

In Verwendung mit Kubernetes wird das ganze jetzt zu einer Dauerschleife. Beheben kann ich das ganze anscheinend indem ich innerhalb des Containers “./pg_resetwal /var/lib/postgresql/data” ausführe, allerdings manuell.

Nun soll das System sich aber im Fehlerfall bestmöglichst selbst helfen. Ich könnte also

  • Dafür sorgen das das WAL nicht korrumpiert (e.g. weniger anfälliges Dateisystem nehmen?)
  • Eventuell eine Art Clustering/HA einrichten (wenn das WAL durch einen Fehler im Dateisystem korrumpiert wird sollte das ja nicht auf zwei Systemen gleichzeitig passieren)
  • Im falle eines “PANIC: could not locate a valid checkpoint record” den oben genannten Befehl zum resetten des WAL automatisch ausführen, e.g. durch einen Site-Car Container mit im gleichen Kubernetes-Pod oder ich stelle den Befehl einfach prophylaktisch vor den Startbefehl des Docker-Containers (Mit allen Nachteilen die das mit sich bringt. Also…, ich gehe mal davon aus das es Nachteile gibt, sonst könnte postgres das ja auch einfach selbst machen?)

Würde mich freuen wenn jemand zu den drei oben genannten Punkten seine Meinung beisteuern könnte oder mich auf andere Best Practices hinweist um zu vermeiden dass die DB nicht mehr startet weil das WAL kaputt ist.

ich kann dem ganzen Docker/K8s - Zeugs nicht viel abgewinnen, um ehrlich zu sein. Wenn das WAL kapott ist, dann hast ein Problem, welches eher nicht automatisiert behoben werden kann. Um dem vorzubeugen hat man a) ein robustes Filesystem, b) ein RAID und c) eine HA-Umgebung mit Replikation.

Sehe ich genauso. Die Technologien wurde für stateless System entwickelt. Eine Datenbank ist aber per Definition statefull.

Das hier finde ich recht interessant: https://cloud.google.com/blog/products/databases/to-run-or-not-to-run-a-database-on-kubernetes-what-to-consider

Wenn man das Deployment einer Datenbank automatisieren will, ist meiner Meinung nach Ansible die bessere Wahl.

@akretschmer und @castorp, vielen dank für eure Antworten. Insbesondere vielen Dank für den Link von castorp, ich werde mir mal die Projekte https://github.com/CrunchyData/postgres-operator und https://github.com/zalando/patroni genauer anschauen. Und ja, ich würde eine Datenbank wenn möglich auch nicht in Container reinstopfen aber in meinem Fall hat es zu viele Vorteile wenn alles unter einem Hut (in meinem Fall Kubernetes) läuft. Auf jeden Fall vielen Dank :slight_smile: