3-2-1 Backup-Strategie
Backups die nicht getestet wurden sind keine Backups. Das klingt nach Klischee bis man ein Backup zurückspielen muss und feststellt dass es seit zwei Monaten leer ist.
Die 3-2-1-Regel
- 3 Kopien der Daten
- auf 2 verschiedenen Medien/Systemen
- davon 1 Off-Site
Konkret: Produktivdatenbank, Backup auf demselben Server, Backup auf einem anderen Server oder in Cloud-Storage.
Datenbankbackup automatisieren
#!/bin/bash
set -euo pipefail
DB_NAME="myapp"
BACKUP_DIR="/backup/db"
TIMESTAMP=$(date +%Y-%m-%d_%H-%M)
FILE="$BACKUP_DIR/${DB_NAME}_${TIMESTAMP}.sql.gz"
mkdir -p "$BACKUP_DIR"
mysqldump \
--single-transaction \
--quick \
--lock-tables=false \
"$DB_NAME" | gzip > "$FILE"
# Alte Backups löschen (>30 Tage)
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +30 -delete
# Erfolg melden
curl -fsS "https://hc-ping.com/${HEALTHCHECK_UUID}" > /dev/null
--single-transaction macht ein konsistentes Backup ohne Tabellen zu sperren — für InnoDB wichtig.
Dateien mit rsync Off-Site
rsync -az --delete \
/backup/ \
backup-user@offsite-server:/backup/myapp/
Rclone für Cloud-Storage
rclone copy /backup s3:my-bucket/backups \
--transfers 4 \
--s3-storage-class STANDARD_IA # günstiger für selten abgerufene Daten
Funktioniert mit S3, Backblaze B2, Hetzner Object Storage und Dutzenden anderen Anbietern.
Verschlüsselung
# Backup verschlüsseln bevor Upload
gpg --batch --yes \
--recipient backup@example.com \
--encrypt "$FILE"
# Unverschlüsseltes Backup lokal löschen
rm "$FILE"
Off-Site-Backups sollten immer verschlüsselt sein — man gibt sie aus der Hand.
Restore testen
Einmal pro Monat ein Backup zurückspielen. In eine Testdatenbank, nicht in Produktion.
# Test-Restore gunzip < backup_2023-07-24.sql.gz | mysql myapp_test mysql myapp_test -e "SELECT COUNT(*) FROM users;"
Ein Backup das man nie restored hat ist eine Hoffnung, kein Plan.