PostgreSQL-Backup wiederherstellen, ohne die laufende Datenbank zu überschreiben
Eine Migration hat 2.300 Rechnungen beschädigt, das Backup von 3 Uhr ist da. Es über die Produktion zu spielen, löscht alles seit 3 Uhr. Warum die Wiederherstellung in eine neue Datenbank gehört – mit pg_restore Schritt für Schritt.

Donnerstag, 16:30 Uhr. Ein Deploy um 14:10 enthielt eine Migration, die in invoices die Spalte paid_at für 2.300 Zeilen auf NULL gesetzt hat. Seitdem bekommen zahlende Kunden Mahnungen. Das Backup von 3 Uhr nachts ist da, der Reflex liegt nahe: pg_restore --clean -d shop backup.dump gegen die Produktion. Die 2.300 Zeilen wären repariert – und alles seit 3 Uhr weg: 412 neue Bestellungen, 90 Registrierungen, jede Zahlung des Tages.
Ein PostgreSQL-Backup wiederherzustellen heißt, den gesicherten Stand einer Datenbank zurückzuschreiben – und die wichtigste Entscheidung ist, wohin. Wer nach „postgresql backup wiederherstellen“ sucht, findet meist den Befehl, selten diese Frage. Die sichere Antwort ist fast immer: in eine neue Datenbank.
Welche Arten von PostgreSQL-Backups gibt es?
Die PostgreSQL-Dokumentation unterscheidet drei Ansätze, und sie bestimmen, was Sie wiederherstellen können:
- SQL-Dump (logisch).
pg_dumpexportiert genau eine Datenbank, konsistent auch im laufenden Betrieb. Im Custom-Format (-Fc) ist der Dump komprimiert und lässt sich mitpg_restoregezielt zurückspielen; ein reiner SQL-Dump gehört inpsql. Rollen fehlen – die exportiert nurpg_dumpall. - Dateisystem-Backup oder Snapshot (physisch). Eine Kopie der Datendateien oder des Volumes, immer der ganze Cluster mit allen Datenbanken.
- Kontinuierliche Archivierung (Point-in-Time Recovery). Basis-Backup plus archiviertes WAL: Wiederherstellung auf jeden Zeitpunkt seit dem Basis-Backup – laut Doku ebenfalls nur für den ganzen Cluster.
Gezielt in eine einzelne Datenbank zurückspielen lässt sich also nur ein logisches Backup.
Warum gehört die Wiederherstellung in eine neue Datenbank?
- Die Produktion läuft weiter. Bestellungen, Zahlungen und Registrierungen seit dem Backup bleiben erhalten.
- Sie können vergleichen. Alter und neuer Stand liegen nebeneinander; Sie sehen, welche Zeilen wirklich betroffen sind.
- Sie holen nur zurück, was fehlt. Meist eine Tabelle oder ein paar tausend Zeilen, nicht die ganze Datenbank.
- Ein Fehlschlag kostet nichts. Bricht die Wiederherstellung ab, ist eine leere Datenbank kaputt, nicht die Produktion.
- Sie schalten bewusst um. Ist der alte Stand wirklich besser, wechseln Sie die Verbindung zu einem Zeitpunkt Ihrer Wahl.
Wie stelle ich ein Backup mit pg_restore in eine neue Datenbank wieder her?
- Prüfen, was Sie haben.
pg_restore -l backup.dumplistet den Inhalt eines Archivs. Scheitert das, ist es vermutlich ein reiner SQL-Dump fürpsql. - Leere Datenbank anlegen.
CREATE DATABASE shop_restore TEMPLATE template0;– template0 ist laut Doku die Vorlage ohne lokale Ergänzungen. - Zurückspielen.
pg_restore --no-owner --no-privileges -d shop_restore -j 4 backup.dump.--no-ownermacht den verbindenden Benutzer zum Eigentümer aller Objekte,--no-privilegeslässt die GRANTs weg,-j 4lädt parallel (nur Custom- und Directory-Format),-t invoicesholt eine einzelne Tabelle. - Prüfen. Zeilenzahlen und
SELECT max(created_at) FROM orders;zeigen, welchen Stand Sie vor sich haben.
Nicht hierher gehören zwei Optionen: --clean, laut Doku zum Überschreiben einer bestehenden Datenbank gedacht, und --create. Damit dient die Datenbank aus -d nur noch für CREATE DATABASE, die Daten landen im Namen aus dem Archiv – auf demselben Server also in der Produktion, mit --clean vorher gelöscht.
Eigentümer und Rechte: Warum sieht der Lesenutzer plötzlich nichts?
Ohne --no-owner will pg_restore jedem Objekt seinen alten Eigentümer geben; das scheitert laut Doku ohne Superuser-Rechte, sofern Sie nicht als genau dieser Eigentümer verbunden sind. Mit --no-owner gehört alles dem, der wiederherstellt. Die Folgen:
- Verbindet sich die App als anderer Benutzer, bekommt sie „permission denied“, bis sie Rechte erhält oder als neuer Eigentümer verbindet.
--no-privilegesbringt keine GRANTs mit, auch nicht die Ihres Lesenutzers für Auswertungen – der sieht nichts.ALTER DEFAULT PRIVILEGESgilt laut Doku nur für Objekte, die eine bestimmte Rolle künftig anlegt. Für einen neuen Eigentümer setzen Sie sie neu, sonst ist der Lesenutzer nach der nächsten Migration wieder blind.
Mehr zu Rollen und Default Privileges pro Service im Beitrag Eine Datenbank pro Service.
Zurückkopieren oder umschalten?
Meist ist nur ein Teil kaputt. Dann kopieren Sie zurück, mit einem Haken: Eine PostgreSQL-Verbindung sieht laut Doku nur eine Datenbank, ein Join zwischen Produktion und Wiederherstellung geht nicht. Der Weg führt über eine Datei:
- Wiederhergestellte Datenbank:
\copy (SELECT id, paid_at FROM invoices) TO 'fix.csv' CSV - Produktion: Hilfstabelle
fixanlegen und mit\copy fix FROM 'fix.csv' CSVfüllen. - In einer Transaktion
UPDATE invoices i SET paid_at = f.paid_at FROM fix f WHERE i.id = f.id AND i.paid_at IS NULL;, Zeilenzahl prüfen, dannCOMMIT.
Ist die ganze Datenbank unbrauchbar, schalten Sie um: DATABASE_URL der App auf die neue Datenbank, neu starten; was seit dem Backup in der alten landete, ziehen Sie bewusst nach. Danach aufräumen: die alte Datenbank einige Tage als Beleg behalten, dann löschen – und heruntergeladene Dumps mit Kundendaten von Laptops entfernen.
Was bietet Scaleway Managed Database für PostgreSQL?
- Automatische Backups sind bei Block Storage Snapshots der ganzen Instanz, standardmäßig täglich und sieben Tage aufbewahrt; wiederhergestellt wird in eine neue, zusätzlich berechnete Instanz.
- Logische Backups einer Datenbank legen Sie bei Block Storage manuell an (laut Doku bis 585 GB Speicher); bei lokalem Speicher sind die automatischen Backups logisch. Beim Wiederherstellen fragt die Konsole: ursprüngliche oder neue Datenbank? Nehmen Sie die neue.
- Export: „Prepare export“, dann „Download“. PostgreSQL-Backups kommen im komprimierten PostgreSQL-Format;
pg_restore -lzeigt, ob es ein Archiv ist.
Wie Clusterward das umsetzt
Für Datenbanken, die Clusterward verwaltet (siehe Managed Datenbanken), zeigt die Instanzseite die Karte „Backups“: automatische Snapshots mit änderbarem Zeitplan und Datenbank-Backups, die Sie mit „Back up now“ anlegen und 7, 30 oder 90 Tage behalten. Heruntergeladen wird über einen kurzlebigen Link, den Clusterward nicht speichert; Snapshots stellen Sie in der verlinkten Scaleway-Konsole wieder her.
„Restore into a new database“ überschreibt nie die laufende Datenbank: Nach Eingabe des Datenbanknamens legt Clusterward daneben db_<name>_r<datum> mit eigenem Benutzer usr_<name>_r<datum> und generiertem Passwort an und lässt Scaleway das Backup hineinspielen. Meldet Scaleway „fertig“, setzt Clusterward die Rechte des neuen Benutzers erneut – die Wiederherstellung legt Tabellen nach der ersten Freigabe an. Vergleichen können Sie nur lesend in der SQL-Konsole; zum Umschalten zeigt die App auf die neue Datenbank, oder Sie weisen sie dem Service zu und starten neu. Die alte bleibt, bis Sie sie löschen. Mehr unter Backups & Wiederherstellung.
Fazit
Ein Backup über die laufende Datenbank zu spielen, repariert den Fehler und vernichtet alles seitdem. In eine neue Datenbank wiederhergestellt, wird es zur Quelle: vergleichen, gezielt zurückkopieren, bewusst umschalten. Planen Sie Eigentümer und Rechte ein, bevor die nächste Mahnung rausgeht.
Ihre Wiederherstellung einmal durchspielen? Erzählen Sie uns, wie Ihre Datenbanken heute gesichert werden. Wir zeigen, wie eine Wiederherstellung ohne Risiko für die Produktion aussieht. Frage stellen →
Quellen und weiterführende Links
Häufige Fragen
- Ja. Ein logisches Backup im Custom-Format spielen Sie mit pg_restore und der Option -d in eine leere Datenbank, etwa eine neu aus template0 angelegte. Mit --no-owner gehören die Objekte dem verbindenden Benutzer. Die Option --create gehört nicht dazu: Mit ihr landen die Daten in dem Namen, der im Archiv steht.