Zum Inhalt

Datenbank-Backup-Automatisierung & Disaster-Recovery-Tests unter Debian

Erstellt: 2026-11-08  ·  Zuletzt aktualisiert: 2026-11-08  ·  Nejat Hakan

Management Summary: Die wichtigste Grundregel im professionellen Systembetrieb lautet: Ein ungetestetes Backup existiert nicht. Unternehmen stellen häufig erst im akuten Katastrophenfall fest, dass Dumps unvollständig sind, Tabellenberechtigungen fehlen oder Zieldatenbanken Integritätsfehler aufweisen. Dieser Praxisleitfaden demonstriert, wie unter Debian Linux eine automatisierte, blockierungsfreie Backup-Pipeline mit Multi-Thread-fähigem pg_dump und moderner Zstandard-Kompression aufgebaut wird, wie kryptografische SHA-256-Prüfsummen Bit-Rot verhindern und wie eine automatisierte Sandbox-Restore-Pipeline die Wiederherstellbarkeit täglich garantiert.

  • Parallele Dumps & Kompression


    Backup-Fenster minimieren: Einsatz von pg_dump -Fd -j 4 mit Zstandard (zstd) für extrem schnelle und kompakte Archive.

  • Integritätsprüfung via Prüfsummen


    Schutz vor fehlerhaften Speicherblöcken: Automatische Berechnung von SHA-256-Hashes direkt nach Fertigstellung des Dumps.

  • Automatisierte Restore-Tests


    Wiederherstellbarkeit täglich beweisen: Automatisierter täglicher Import des Dumps in eine isolierte Sandbox-Testdatenbank.

  • Retention & Zeitsteuerung


    Festplattenüberlauf verhindern: Durchsetzung strikter Vorhaltefristen (Retention) via Shell-Rotation und Cron-/Systemd-Timer.


1. Backup-Strategien: Logisch vs. Physisch

Enterprise-Datenbanken erfordern zwei sich ergänzende Ebenen der Datensicherung:

%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
    DB["Live-Produktions-DB<br/>(PostgreSQL / MariaDB)"]
    DUMP["Dump Engine<br/>pg_dump -j 4 mit Zstd 3"]
    ARCHIVE["Verschlüsselter Speicher<br/>Archiv + SHA-256 Checksum"]
    RESTORE["Sandbox Restore Pipeline<br/>Temporäre Test-DB starten"]
    SANITY{"Integritätsprüfung<br/>Zeilen & Constraints"}
    REPORT["Telemetrie & Alerting<br/>Webhook OK"]

    DB -->|"MVCC-Read"| DUMP
    DUMP -->|"Schreibt Archive"| ARCHIVE
    ARCHIVE -->|"Lädt Snapshot"| RESTORE
    RESTORE --> SANITY
    SANITY -->|"Pass (Test-DB löschen)"| REPORT

Strategischer Vergleich

Kriterium Logische Backups (pg_dump, mariadb-dump) Physische Backups (pg_basebackup, LVM)
Datenformat SQL-DDL-Befehle und Datensätze (portables Format). Binäre Speicherdateien und WAL-Blöcke.
Geschwindigkeit Bei Multi-Terabyte-Instanzen langsamer. Extrem schnell auf Block- und I/O-Ebene.
Granularität Einzelne Tabellen, Schemas oder Datenbanken. Immer nur die gesamte Datenbankinstanz/Cluster.
Versionsportabilität Sehr hoch (ideal für Major-Upgrades z. B. PG15 → PG16). Gering (strikt an exakte Major-Version und Architektur gebunden).
Haupteinsatzzweck Disaster Recovery, Datenprüfungen, Sandbox-Testing. Hochverfügbarkeits-Replikation und Bare-Metal-Restore.

2. PostgreSQL-Backup-Engine im Produktivbetrieb

Logische Backups dürfen niemals Schreib- oder Lesezugriffe der Webanwendung blockieren. pg_dump liest die Daten konsistent über eine MVCC-Transaktion auf Isolationsebene REPEATABLE READ, sodass der reguläre Betrieb unbeeinflusst weiterläuft.

2.1. Optimierte Backup-Syntax

Für große Datenbanken wird das Verzeichnisformat (-Fd) genutzt, das parallele Multi-Core-Dumps (-j) und moderne Zstandard-Kompression unterstützt:

pg_dump \
    -h 127.0.0.1 \
    -p 5432 \
    -U postgres \
    -d enterprise_prod \
    -Fd \
    -j 4 \
    --compress=zstd:3 \
    -f /var/backups/postgresql/enterprise_prod_$(date +%Y%m%d_%H%M%S).dumpdir
  • -Fd: Verzeichnisformat (speichert Tabellen in Teildateien, Voraussetzung für parallelen Restore).
  • -j 4: Nutzt 4 parallele CPU-Threads zum gleichzeitigen Dumpen von Tabellen.
  • --compress=zstd:3: Zstandard Level 3 (deutlich schneller und speichereffizienter als veraltetes Gzip).

3. Gehärtetes Backup-Skript für Debian

Installieren Sie dieses produktionsreife Automatisierungsskript auf Ihrem Server:

#!/usr/bin/env bash
# Datei: /opt/db-ops/backup_databases.sh
set -euo pipefail

# 1. Pfad- und Umgebungskonfiguration
BACKUP_DIR="/var/backups/postgresql"
DATE_TAG="$(date +%Y%m%d_%H%M%S)"
TARGET_DIR="${BACKUP_DIR}/enterprise_prod_${DATE_TAG}.dumpdir"
CHECKSUM_FILE="${TARGET_DIR}.sha256"
LOG_FILE="/var/log/db_backups.log"
RETENTION_DAYS=14

mkdir -p "${BACKUP_DIR}"
exec > >(tee -a "${LOG_FILE}") 2>&1

echo "============================================================"
echo "Start des Datenbank-Backups: $(date --iso-8601=seconds)"
echo "Zielverzeichnis: ${TARGET_DIR}"
echo "============================================================"

# 2. Parallelen logischen Dump ausführen
sudo -u postgres pg_dump \
    -d enterprise_prod \
    -Fd \
    -j 4 \
    --compress=zstd:3 \
    -f "${TARGET_DIR}"

# 3. Kryptografische SHA-256 Prüfsummen für alle Segmente berechnen
echo "Berechne SHA-256 Prüfsummen..."
find "${TARGET_DIR}" -type f -exec sha256sum {} + > "${CHECKSUM_FILE}"
echo "Prüfsummendatei gespeichert: ${CHECKSUM_FILE}"

# 4. Alte Sicherungen jenseits der Vorhaltezeit bereinigen (Retention)
echo "Bereinige Backups älter als ${RETENTION_DAYS} Tage..."
find "${BACKUP_DIR}" -maxdepth 1 -name "enterprise_prod_*.dumpdir" -mtime "+${RETENTION_DAYS}" -exec rm -rf {} +
find "${BACKUP_DIR}" -maxdepth 1 -name "enterprise_prod_*.sha256" -mtime "+${RETENTION_DAYS}" -delete

echo "Backup und Rotation erfolgreich abgeschlossen: $(date --iso-8601=seconds)"

Ausführungsrechte absichern:

sudo chmod 750 /opt/db-ops/backup_databases.sh
sudo chown root:postgres /opt/db-ops/backup_databases.sh

4. Automatisierte Restore-Tests & Disaster-Recovery-Verifikation

Eine Backupdatei auf der Festplatte hat keinerlei verlässlichen Wert, solange ihre Wiederherstellbarkeit nicht verifiziert wurde. Folgendes Testskript prüft täglich das neueste Backup in einer Sandbox-Datenbank:

#!/usr/bin/env bash
# Datei: /opt/db-ops/verify_restore.sh
set -euo pipefail

BACKUP_DIR="/var/backups/postgresql"
TEST_DB="sandbox_restore_verification"

# 1. Neuesten Dump ermitteln
LATEST_BACKUP="$(find "${BACKUP_DIR}" -maxdepth 1 -name "enterprise_prod_*.dumpdir" -type d | sort | tail -n 1)"
if [ -z "${LATEST_BACKUP}" ]; then
    echo "FEHLER: Kein Backup in ${BACKUP_DIR} gefunden!" >&2
    exit 1
fi

echo "Prüfe jüngstes Backup-Archiv: ${LATEST_BACKUP}"

# 2. SHA-256 Prüfsummen verifizieren
CHECKSUM_FILE="${LATEST_BACKUP}.sha256"
if [ -f "${CHECKSUM_FILE}" ]; then
    echo "Verifiziere SHA-256 Prüfsummen..."
    sha256sum --check "${CHECKSUM_FILE}" --status
    echo "Prüfsummen-Verifikation ERFOLGREICH."
else
    echo "WARNUNG: Keine Prüfsummendatei für ${LATEST_BACKUP} gefunden!"
fi

# 3. Frische Sandbox-Datenbank anlegen
sudo -u postgres psql -c "DROP DATABASE IF EXISTS ${TEST_DB};"
sudo -u postgres psql -c "CREATE DATABASE ${TEST_DB};"

# 4. Multi-Threaded Restore durchführen
echo "Stelle Backup in Sandbox-Datenbank '${TEST_DB}' wieder her..."
sudo -u postgres pg_restore \
    -d "${TEST_DB}" \
    -j 4 \
    --clean \
    --if-exists \
    "${LATEST_BACKUP}"

# 5. Integritätsprüfung ausführen (Tabellenzählung)
echo "Führe Plausibilitätsprüfungen durch..."
RECORD_COUNT=$(sudo -u postgres psql -d "${TEST_DB}" -t -A -c "
    SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';
")

if [ "${RECORD_COUNT}" -eq 0 ]; then
    echo "FATAL: Sandbox-Datenbank enthält nach Restore 0 Tabellen im Schema public!" >&2
    exit 2
fi

echo "Integritätsprüfung ERFOLGREICH: ${RECORD_COUNT} Tabellen im Schema public verifiziert."

# 6. Test-Datenbank aufräumen
sudo -u postgres psql -c "DROP DATABASE ${TEST_DB};"
echo "Disaster-Recovery-Simulation erfolgreich beendet!"

5. Zeitsteuerung via Cron

Führen Sie das Backup nachts um 02:00 Uhr und den automatisierten Wiederherstellungstest um 04:00 Uhr aus:

# Datei: /etc/cron.d/db-backup-automation
# m h dom mon dow user    command
0 2 * * * root /opt/db-ops/backup_databases.sh
0 4 * * * root /opt/db-ops/verify_restore.sh