Postgres Point-in-Time Recovery Kit

Stellen Sie einen PostgreSQL-Server auf den Moment vor dem fatalen DELETE zurück, mit Skripten, die Sie an einem Abend lesen können, und einem Drill, der zeigt, dass sie funktionieren.

Bei Polar kaufen: $39 Einmalkauf · v0.1.0 · Sofort-Download über Polar

Cover von Postgres Point-in-Time Recovery Kit
Ausgabe eines echten Testlaufs, kein Mock-up.

Für wen es ist

Sie betreiben einen PostgreSQL-Server, auf einem VPS oder einer Maschine im Büroschrank, und Ihr Backup ist ein nächtlicher pg_dump. Der schützt Sie vor dem Verlust der Platte. Er hilft nicht, wenn jemand um 10:15 ein DELETE FROM orders ohne WHERE-Klausel ausführt und Sie es um 10:40 bemerken. Der Dump von letzter Nacht wirft Sie 12 Stunden zurück. Mit Point-in-Time Recovery landen Sie bei 10:14.

pgBackRest und Barman sind voll ausgestattete Tools, und es dauert einen Nachmittag, sie zu lernen. Für einen einzelnen kleinen Server ist dieses Kit die Kurzfassung: Bash-Skripte, ein Archiv, ein Cluster, nichts Verstecktes.

Was es kann

  • Kontinuierliche WAL-Archivierung, sicher eingerichtet: Sie überschreibt nie eine Datei, schlägt bei voller oder schreibgeschützter Platte laut fehl, und ein defektes Archiv fällt auf, bevor die Platte vollläuft.
  • Base Backups, die nach dem Erstellen mit pg_verifybackup geprüft, gepackt und gegen eine Prüfsumme kontrolliert werden.
  • Retention, die anhand des ältesten Base Backups, das Sie behalten, bestimmt, was gelöscht wird. So kann sie kein WAL entfernen, das ein behaltenes Backup noch braucht.
  • Restore auf einen Zeitstempel, eine LSN, einen benannten Restore Point oder das neueste archivierte WAL, in ein neues Verzeichnis, wobei die Timeline für Sie erledigt wird.
  • Ein Cron-Monitor, der das Alter des zuletzt archivierten Segments und den Rückstand prüft. Die Alarme per Telegram oder Webhook wiederholen sich nicht und melden, wenn alles wieder in Ordnung ist.
  • Ein Drill, der Daten aufbaut, ein Backup zieht, absichtlich einen Fehler macht, den Server zerstört und ihn in einem sauberen Container wiederherstellt. Anschließend werden Zeilenzahlen und Prüfsummen verglichen.

So sieht die tägliche Nutzung aus

So sehen die täglichen und die Notfall-Befehle aus. Die Skripte sind einfaches Bash, Sie können jedes einzelne lesen.

./backup-base.sh && ./prune.sh          # nightly
./check-archive.sh                      # every 5 minutes, exit code plus alert
./verify-archive.sh                     # daily: is the WAL chain complete?

# the bad DELETE happened around 10:15 UTC
./restore-to-time.sh --target-dir /srv/restore/r1 \
    --time "2026-11-09 10:14:59+00" --start --port 5433
psql -h /tmp -p 5433 -d postgres        # look around, then copy back what you need

Weitere Ziele: --name before_migration (ein von Ihnen angelegter Restore Point), --lsn 0/5000060 und restore-latest.sh für reine Disaster Recovery. Mit der Option --pause hält die Recovery am Ziel an. So können Sie die Daten schreibgeschützt ansehen, bevor Sie entscheiden.

Was es verweigert

Der größte Teil der Arbeit steckte in den Dingen, die nicht stillschweigend schiefgehen dürfen.

  • Ein fehlendes WAL-Segment mitten im Archiv. Der Restore stoppt, nennt das Segment und endet mit einem Exit-Code ungleich null. In unseren Tests lieferte das erzwungene Durchlaufen 200 von 410 Zeilen ohne Fehlermeldung zurück. Genau deshalb verweigert das Kit es standardmäßig.
  • Ein Zielzeitpunkt vor dem ersten Base Backup, ein Restore in ein nicht leeres Datenverzeichnis oder über das laufende, und die Ausführung als root.
  • Das Überschreiben einer archivierten Datei, auch dann, wenn ein wiederhergestellter Server seine Timeline-Nummerierung neu beginnt.
  • Das Löschen von WAL, das ein behaltenes Base Backup braucht.
  • Tablespaces. Das Backup-Skript bricht ab, statt etwas zu erzeugen, das sich nicht wiederherstellen lässt.

Gemessen

Ein Lauf auf einer ARM64-Maschine der Laptop-Klasse, PostgreSQL mit Standardeinstellungen.

Restore-Dauer (Server zerstören, in sauberem Container wiederherstellen)

KleinGroß
Daten200,000 Zeilen in der Haupttabelle, 78 MB5,000,000 Zeilen, 989 MB
Restore gesamt2.4 s42.0 s
davon Start und WAL-Replay2.0 s36.1 s
Zeilenzahlen und Prüfsummenstimmen übereinstimmen überein

Wie viel Sie verlieren können

20 Inserts pro Sekunde, dann kill -9 und ein Restore allein aus dem Archiv. „Verloren“ heißt: Commits, die bestätigt wurden, danach aber fehlten.

archive_timeoutBestätigtWiederhergestelltVerloren
10 s79476430 (neuester verlorener Commit 1.9 s jünger als der wiederhergestellte Stand)
10 s513400113 (6.1 s)
60 s1,8961,175721 (36.0 s)
0 (PostgreSQL-Standard)7400alles seit dem Base Backup

Die letzte Zeile sollten Sie sich merken. Beim Standardwert von archive_timeout und einem ruhigen Server verliert eine ausgefallene Platte alles seit dem letzten Base Backup. Die Anleitung erklärt die Einstellung und ihren Preis: Ein erzwungener Wechsel archiviert eine volle 16-MiB-Datei, sofern Sie nicht komprimieren.

Overhead

pgbench, fünf abwechselnde Durchgänge: Median 5,156 tps bei ausgeschalteter Archivierung, 5,112 mit gzip und 5,167 ohne. Die Unterschiede liegen innerhalb der Streuung von 2 Prozent zwischen den Durchgängen: Auf dieser Maschine zeigte sich kein Overhead durch die Archivierung.

So wurde getestet

122 automatische Checks auf PostgreSQL 15 (Debian-Paket) und erneut auf PostgreSQL 17 (PGDG), in sauberen Debian-12-Containern, dazu auf beiden der Destroy-and-Restore-Drill mit zwei Containern. Sie decken ab: ein defektes Archiv, das das Recycling von WAL stoppt, den Archive-Befehl auf lokalen und SFTP-Zielen, Base Backups mit beschädigter Datei, jedes Restore-Ziel, eine zweite Recovery auf einer neuen Timeline, Retention und alle oben genannten Verweigerungen.

Voraussetzungen

Debian 12 mit dem Debian-Paket für PostgreSQL, ein Cluster, bash, curl für Alarme und openssh-client, falls Sie per SFTP archivieren. Für das Setup brauchen Sie root, für alles andere den Benutzer postgres.

Häufige Fragen

Ich nutze schon pgBackRest. Brauche ich das hier?

Nicht unbedingt. pgBackRest ist ein Werkzeug mit großem Funktionsumfang. Dieses Kit ist für den Fall, dass Sie etwas wollen, das klein genug ist, um es ganz zu lesen, oder um zu verstehen, was pgBackRest für Sie erledigt.

Kann ich eine einzelne Tabelle wiederherstellen?

Sie stellen einen ganzen Cluster zum gewählten Zeitpunkt in ein neues Verzeichnis wieder her und kopieren die benötigte Tabelle von dort heraus. Der Drill arbeitet genau nach diesem Muster.

Funktioniert es mit Docker oder gemanagtem Postgres?

Nein. Es braucht Zugriff auf die Konfiguration und die Dateien des Servers. Bei einem gemanagten Dienst nutzen Sie die Point-in-Time Recovery des Anbieters.

Wie viel Plattenplatz braucht es?

Das hängt vom Schreibvolumen und von archive_timeout ab. Die Anleitung nennt WAL-Volumen für einige Workloads und die Kompressionswerte, die wir gemessen haben.

Lizenz

Sie dürfen es auf Ihren eigenen Servern und denen Ihres Arbeitgebers einsetzen. Die Dateien weiterzuverkaufen oder weiterzugeben ist nicht erlaubt.

Änderungsprotokoll

  • 0.1.0: erstes Release.

Weiterlesen

Herunterladen

Bei Polar kaufen: $39

Zahlung, Steuern und Rechnung übernimmt Polar als Merchant of Record. Den Download-Link erhalten Sie nach dem Checkout.