managarten/docs/POSTGRES_BACKUP.md
Till JS fcd7c82ce4 fix(infra): simplify PostgreSQL backup to pg_dumpall + pg_basebackup
pgBackRest as Docker sidecar was overly complex (needs shared WAL
directory, stanza management, special entrypoint). Replace with a
simpler, proven approach using native PostgreSQL tools:

Backup container (postgres:16-alpine):
- Hourly: pg_dumpall | gzip (all databases as SQL, ~2 day retention)
- Daily 03:00: pg_basebackup -Ft -z (physical backup, 30 day retention)
- Auto-cleanup of old backups
- Storage: /Volumes/ManaData/backups/postgres/

Also: Remove pgbackrest.conf, simplify postgresql.conf (remove WAL
archiving config, keep performance tuning + replication for basebackup)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:39:20 +01:00

4 KiB

PostgreSQL Backup

Stündliche Dumps + tägliche Base-Backups für alle Mana-Datenbanken

Übersicht

Aspekt Vorher Jetzt
Frequenz 1x täglich (03:00) Stündlich + täglich
Max. Datenverlust 24 Stunden 1 Stunde
Backup-Typ Nur pg_dumpall pg_dumpall (stündlich) + pg_basebackup (täglich)
Kompression Keine gzip
Retention 30 Tage 48h Dumps + 30 Tage Base-Backups
Automatisch LaunchAgent Cron Docker Container (always running)

Architektur

PostgreSQL (mana-infra-postgres)
    │
    └── postgres-backup Container (mana-infra-postgres-backup)
        ├── Jede Stunde → pg_dumpall | gzip  (alle DBs als SQL)
        └── Täglich 03:00 → pg_basebackup -Ft -z  (physisches Backup)

Backup-Speicherort

/Volumes/ManaData/backups/postgres/
├── hourly_20260324_140000.sql.gz    # SQL Dump (stündlich)
├── hourly_20260324_150000.sql.gz
├── ...
├── base_20260324_030000/            # Base Backup (täglich)
│   ├── base.tar.gz
│   └── pg_wal.tar.gz
└── base_20260323_030000/

Retention:

  • Stündliche Dumps: 48 Stück (~2 Tage)
  • Tägliche Base-Backups: 30 Stück (~1 Monat)

Container-Status prüfen

# Container Status
docker ps --filter name=mana-infra-postgres-backup

# Logs (letzte Backups)
docker logs mana-infra-postgres-backup --tail 20

# Backup-Größe
du -sh /Volumes/ManaData/backups/postgres/
ls -lah /Volumes/ManaData/backups/postgres/hourly_*.sql.gz | tail -5

Wiederherstellung

Szenario 1: Aus stündlichem Dump (SQL)

# 1. Gewünschten Dump finden
ls -la /Volumes/ManaData/backups/postgres/hourly_*.sql.gz

# 2. Alle Datenbanken wiederherstellen
gunzip -c /Volumes/ManaData/backups/postgres/hourly_20260324_140000.sql.gz \
  | docker exec -i mana-infra-postgres psql -U postgres

# 3. Oder einzelne Datenbank:
gunzip -c /Volumes/ManaData/backups/postgres/hourly_20260324_140000.sql.gz \
  | grep -A 99999 'connect chat_db' | grep -B 99999 'connect ' \
  | docker exec -i mana-infra-postgres psql -U postgres -d chat_db

Szenario 2: Aus Base-Backup (physisch)

# 1. PostgreSQL stoppen
docker compose -f docker-compose.macmini.yml stop postgres

# 2. Altes Datenverzeichnis sichern
sudo mv /Volumes/ManaData/postgres /Volumes/ManaData/postgres.broken

# 3. Neues Verzeichnis aus Backup erstellen
sudo mkdir -p /Volumes/ManaData/postgres
cd /Volumes/ManaData/postgres
sudo tar xzf /Volumes/ManaData/backups/postgres/base_20260324_030000/base.tar.gz
sudo tar xzf /Volumes/ManaData/backups/postgres/base_20260324_030000/pg_wal.tar.gz -C pg_wal/
sudo chown -R 70:70 /Volumes/ManaData/postgres

# 4. PostgreSQL starten
docker compose -f docker-compose.macmini.yml start postgres

# 5. Prüfen
docker exec mana-infra-postgres psql -U postgres -c "\l"

Szenario 3: Einzelne Datenbank aus Dump

# Chat-DB wiederherstellen (Drop + Recreate)
docker exec mana-infra-postgres psql -U postgres -c "DROP DATABASE IF EXISTS chat_db;"
docker exec mana-infra-postgres psql -U postgres -c "CREATE DATABASE chat_db;"

gunzip -c /Volumes/ManaData/backups/postgres/hourly_20260324_140000.sql.gz \
  | docker exec -i mana-infra-postgres psql -U postgres -d chat_db

Manuelles Backup

# Sofortiger Dump
docker exec mana-infra-postgres pg_dumpall -U postgres | gzip > /Volumes/ManaData/backups/postgres/manual_$(date +%Y%m%d_%H%M%S).sql.gz

# Sofortiges Base-Backup
mkdir -p /Volumes/ManaData/backups/postgres/manual_base_$(date +%Y%m%d)
docker exec mana-infra-postgres pg_basebackup -U postgres -D /tmp/backup -Ft -z -P
docker cp mana-infra-postgres:/tmp/backup /Volumes/ManaData/backups/postgres/manual_base_$(date +%Y%m%d)

Erste Einrichtung

# Backup-Verzeichnis erstellen
sudo mkdir -p /Volumes/ManaData/backups/postgres

# Container starten
docker compose -f docker-compose.macmini.yml up -d postgres-backup

# Prüfen ob Backup läuft
docker logs mana-infra-postgres-backup --tail 5