pg_dump -h host -U postgres -d shop -Fc -f shop.dump zieht einen komprimierten Dump, den pg_restore -d shop_copy shop.dump wieder einspielt. Bevor das überhaupt läuft, muss der Client mindestens so neu sein wie der Server: ein älteres pg_dump verweigert rundheraus, und genau dieser eine Fehler ist der häufigste Grund, warum eine Sicherung nie entsteht.
1. Der Fehler, an dem alles hängen bleibt
$ clai ziehe einen dump der datenbank shop vom server pg17→ pg_dump -h pg17 -U postgres -d shoppg_dump: error: aborting because of server version mismatchpg_dump: detail: server version: 17.10; pg_dump version: 16.14 (Debian 16.14-1.pgdg13+1)
Kein Flag repariert das. Es braucht einen Client der passenden Version — das Paket postgresql-client-17 oder schlicht dasselbe Container-Image wie der Server. Umgekehrt ist alles gut: ein neuerer Client sichert einen älteren Server anstandslos.
2. Ein Dump im Custom-Format statt einer .sql-Datei
$ clai sichere die datenbank shop in eine binärdatei→ pg_dump -h pg17 -U postgres -d shop -Fc -f shop.dump
-Fc schreibt ein komprimiertes Archiv, das pg_restore selektiv öffnen und mit -j parallel einspielen kann. Eine einfache .sql kann beides nicht — sie läuft komplett und der Reihe nach durch psql.
3. Vor dem Zurückspielen hineinschauen
$ clai zeige was in dem dump steckt→ pg_restore -l shop.dump218; 1259 16386 TABLE public orders postgres217; 1259 16385 SEQUENCE public orders_id_seq postgres3427; 0 0 SEQUENCE OWNED BY public orders_id_seq postgres3271; 2604 16389 DEFAULT public orders id postgres3420; 0 16386 TABLE DATA public orders postgres
Das ist das Inhaltsverzeichnis. In eine Datei speichern, unerwünschte Zeilen löschen und mit -L zurückgeben — so macht man selektive Restores sauber.
4. In eine andere Datenbank zurückspielen
$ clai spiele den dump in die datenbank shop_copy zurück→ pg_restore -h pg17 -U postgres -d shop_copy shop.dump
Die Datenbank muss vorher existieren — createdb shop_copy —, denn ohne -C legt pg_restore sie nicht an. Bei Erfolg sagt der Befehl gar nichts, prüfen Sie also mit select count(*).
5. Nur eine Tabelle, nur Daten
$ clai exportiere nur die tabelle orders ohne schema→ pg_dump -h pg17 -U postgres -d shop -t orders --data-only -f orders-data.sql
-t engt auf ein Objekt ein, --data-only lässt das CREATE TABLE weg. Praktisch, wenn die Zieltabelle schon in gleicher Form existiert und nur die Zeilen fehlen.
6. Zurückspielen auf eine nicht leere Datenbank
$ clai spiele den dump über die bestehende datenbank→ pg_restore -h pg17 -U postgres -d shop_copy --clean --if-exists shop.dump
Ohne --clean scheitert derselbe Dump beim zweiten Mal an pg_restore: error: could not execute query: ERROR: relation "orders" already exists. --clean löscht Objekte vor dem Neuanlegen, --if-exists schluckt die Fehler bei Objekten, die es noch nicht gibt.
Gotchas
- Ein älterer Client sichert einen neueren Server gar nicht. Geprüft: pg_dump 16.14 gegen Server 17.10 bricht sofort ab. Halten Sie den Client mindestens so neu wie den Server; mit Containern startet man pg_dump am einfachsten aus dem Image des Servers.
pg_restore -thängt an, es ersetzt nicht. Eine Tabelle in eine Datenbank zurückzuspielen, in der sie schon Zeilen hat, ergibtERROR: duplicate key value violates unique constraint "orders_pkey". Erst truncate, dann restore.pg_restoreendet auch nach Fehlern mit 0. Geprüft: beim Schlüsselkonflikt druckte es den Fehler und lieferte trotzdem Exit-Code 0. In Skripten--exit-on-errorergänzen, sonst sieht ein kaputter Restore wie ein erfolgreicher aus.
Related questions
Wie sichere ich nur das Schema? pg_dump --schema-only liefert die Struktur ohne Zeilen, --data-only ist das Spiegelbild.
Womit spiele ich einen .sql-Dump ein? psql -d name -f dump.sql. pg_restore versteht nur die Formate -Fc, -Fd und -Ft — Klartext gehört nicht dazu.
Wie beschleunige ich einen großen Restore? pg_restore -j 4 lädt Daten und baut Indizes parallel. Das geht nur mit Custom- und Directory-Format.
See also
CliAI schreibt die Dump- und Restore-Zeilen mit den passenden Flags und zeigt sie, bevor eine davon Ihre Datenbank anfasst. In einer Zeile installieren.