Ein häufiger Fehler in Produktions-Setups: pg_dump-Skripte laufen als Superuser, weil das „auf Anhieb funktioniert hat”. Sicherheitstechnisch unsinnig — eine dedizierte Backup-Rolle kann denselben Job mit minimalen Rechten erledigen. Und wenn du Streaming-Replikation oder physische Backups (pg_basebackup) brauchst, kommt nur ein zusätzliches Attribut dazu.
Variante 1 — Logischer Backup-User (pg_dump / pg_dumpall)
Für pg_dump reichen Lese-Rechte auf alles:
CREATE ROLE backup_user
WITH LOGIN
PASSWORD 'changeme'
CONNECTION LIMIT 2;
GRANT pg_read_all_data TO backup_user;
-- Optional, aber sinnvoll: Connection-Recht explizit setzen
GRANT CONNECT ON DATABASE myapp TO backup_user;pg_read_all_data (PG 14+) umfasst SELECT auf alle Tabellen, Views, Sequenzen — auch zukünftige. Ohne diese Predefined Role müsstest du auf jedem Schema einzeln granten, was bei wachsenden Datenbanken Wartungsaufwand wäre.
Anschließend in pg_hba.conf eine passende Auth-Zeile:
host all backup_user 127.0.0.1/32 scram-sha-256Aufruf von einem Backup-Skript aus:
export PGPASSWORD="$(cat /etc/postgres-backup.pass)"
pg_dump -h localhost -U backup_user -d myapp \
--format=custom \
--file="/var/backups/myapp-$(date +%F).dump"Wichtig: das Passwort niemals als Klartext-Argument auf der Kommandozeile (taucht in ps auf). Stattdessen ~/.pgpass, PGPASSWORD aus einer geschützten Datei oder ein Secret-Manager-Plugin.
Variante 2 — Cluster-weiter Dump (pg_dumpall)
pg_dumpall schreibt Rollen, Globals und alle Datenbanken in einen Stream. Dafür braucht der User zusätzlich Zugriff auf System-Kataloge auf Cluster-Ebene:
ALTER ROLE backup_user WITH SUPERUSER;Hier wird’s unangenehm: für pg_dumpall --globals-only (Rollen, Tablespaces, Cluster-Privilegien) braucht der User echten Superuser-Status, weil die Rollen-Hashes in pg_authid nur Superuser sehen. Ohne diese Information wäre der Dump unvollständig.
In Produktion bedeutet das: entweder akzeptieren, dass der Backup-User Superuser ist (und dafür sehr eingeschränkten Netzwerk-Zugriff bekommen), oder mit pg_dumpall --no-role-passwords --globals-only arbeiten und auf die Passwort-Hashes verzichten.
Variante 3 — Physisches Backup (pg_basebackup, Streaming-Replikation)
Für pg_basebackup oder als Source einer Replika braucht es das REPLICATION-Attribut und einen passenden Eintrag in pg_hba.conf:
CREATE ROLE replicator
WITH LOGIN
REPLICATION
PASSWORD 'changeme'
CONNECTION LIMIT 5;pg_hba.conf braucht eine eigene Zeile mit Database replication:
host replication replicator 10.0.0.0/24 scram-sha-256Anwendung:
pg_basebackup -h primary.example.com -U replicator \
-D /var/lib/postgresql/18/standby \
--checkpoint=fast \
--write-recovery-conf \
--wal-method=streamFür ein vollständiges Replika-Setup zusätzlich wal_level >= replica (Default ab PG 10) und max_wal_senders-Konfiguration auf der Primary — ist Thema des Replikation-Kapitels.
Variante 4 — Logische Replikation (PUBLICATION/SUBSCRIPTION)
Seit PG 16 gibt es pg_create_subscription als Predefined Role:
CREATE ROLE logical_replica
WITH LOGIN
REPLICATION
PASSWORD 'changeme';
GRANT pg_create_subscription TO logical_replica;Damit kann logical_replica selbst CREATE SUBSCRIPTION ausführen — vorher Superuser-only. Nützlich, wenn der Subscription-Aufbau aus Skripten heraus passiert, ohne dass jeder Operator Superuser-Rechte braucht.
Backup-User-Setup als Skript
Ein Bootstrap-Skript, das alle drei Varianten kombiniert anlegt — typisch für Produktions-Setups, wo mehrere Backup-Tools parallel arbeiten:
-- Logischer Backup (pg_dump)
CREATE ROLE backup_logical
WITH LOGIN
PASSWORD 'changeme'
CONNECTION LIMIT 2;
GRANT pg_read_all_data TO backup_logical;
-- Physischer Backup (pg_basebackup) und Streaming-Replikation
CREATE ROLE backup_physical
WITH LOGIN
REPLICATION
PASSWORD 'changeme'
CONNECTION LIMIT 5;
-- Beide CONNECT-Berechtigt auf jede DB:
GRANT CONNECT ON DATABASE myapp TO backup_logical;
GRANT CONNECT ON DATABASE analytics TO backup_logical;Besonderheiten
Backup-User braucht keinen SUPERUSER fuer pg_dump.
Ein häufiges Anti-Pattern in Tutorials: der Backup-User wird als Superuser angelegt. Tatsächlich reicht pg_read_all_data für pg_dump einer einzelnen Datenbank vollständig. Den Superuser-Status nur dort vergeben, wo er wirklich nötig ist — typischerweise nur bei pg_dumpall --globals-only mit Rollen-Passwörtern.
REPLICATION ist eine eigene Database-Klasse in pg_hba.conf.
Die Zeile host all replicator … reicht NICHT für Streaming-Replikation. Postgres prüft beim Walsender-Connect die spezielle Database replication — du brauchst eine separate Zeile mit genau diesem Wert in der DATABASE-Spalte. Diese Falle kostet typisch 30 Minuten beim ersten Setup.
Backup-User auf Cloud-Postgres unterscheidet sich.
Auf RDS/Cloud SQL gibt es keinen direkten Filesystem-Zugriff. pg_basebackup von außen funktioniert oft, ist aber nicht der vorgesehene Weg — Cloud-Anbieter haben eigene Backup-Mechanismen (Snapshots, automated backups). Logische Backups via pg_dump von extern gehen weiterhin und sind sinnvoll als zusätzliche Sicherheitsschicht.
Connection-Limit fuer Backup-User schuetzt vor sich selbst.
Wer 10 parallel laufende Cron-Jobs hat, die alle pg_dump auslösen, kann ohne Limit den ganzen Connection-Pool blockieren. CONNECTION LIMIT 2 (oder so) verhindert das — das zweite Backup wartet, statt produktiven Traffic zu verdrängen.
pg_dump --no-acl --no-owner fuer portable Dumps.
Wer einen Dump auf einer anderen Maschine restoren will (z. B. von Production zu Staging), bekommt mit Standard-Dumps oft Owner-Konflikte: die Production-Owner-Rollen existieren auf Staging nicht. --no-acl --no-owner lässt diese Anweisungen weg; beim Restore landet alles beim aktuellen User.
Backup-Frequenz vs. WAL-Archivierung — eine Architekturfrage.
Ein einzelner pg_dump pro Tag ist für viele Setups zu wenig (bis zu 24h Datenverlust möglich). Production-Setups kombinieren typisch: täglicher logischer Dump als Long-Term-Archive + WAL-Archivierung für Point-in-Time-Recovery. Die hier angelegten Rollen sind die Voraussetzung — die Strategie selbst gehört ins Backup-Kapitel.
Weiterführende Ressourcen
Externe Quellen
- pg_dump – PostgreSQL Documentation
- pg_dumpall – PostgreSQL Documentation
- pg_basebackup – PostgreSQL Documentation
- Predefined Roles – PostgreSQL Documentation
- Streaming Replication