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:

SQL Backup-User fuer logische Dumps
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:

Bash pg_hba.conf
host    all    backup_user    127.0.0.1/32    scram-sha-256

Aufruf von einem Backup-Skript aus:

Bash Cron-Job
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:

SQL Erweiterung fuer pg_dumpall
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:

SQL Replication-Rolle
CREATE ROLE replicator
    WITH LOGIN
         REPLICATION
         PASSWORD 'changeme'
         CONNECTION LIMIT 5;

pg_hba.conf braucht eine eigene Zeile mit Database replication:

Bash pg_hba.conf
host    replication    replicator    10.0.0.0/24    scram-sha-256

Anwendung:

Bash pg_basebackup
pg_basebackup -h primary.example.com -U replicator \
    -D /var/lib/postgresql/18/standby \
    --checkpoint=fast \
    --write-recovery-conf \
    --wal-method=stream

Fü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:

SQL
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:

SQL bootstrap-backups.sql
-- 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

/ Weiter

Zurück zu Server-Administration

Zur Übersicht