Backup-Sanity-Checks sind kurze, automatisierte Schnellrestore‑Tests, die täglich bestätigen, dass kritische Datenpfade tatsächlich wiederherstellbar sind. Ziel ist nicht ein kompletter Disaster‑Recovery‑Durchlauf, sondern ein schneller, reproduzierbarer Smoke‑Test, der Keys, Transport, Entschlüsselung und minimale Plausibilitätsprüfungen umfasst. Dieser Beitrag richtet sich an Administratoren, System Engineers und Betreiber und erklärt Voraussetzungen, typische Stolperfallen, konkrete Prüfsequenzen und eine praktikable Rückfallstrategie – mit besonderem Augenmerk auf MySQL.
Backup-Sanity-Checks: Warum ein erfolgreicher Backup‑Job nicht genügt
Backup-Tools melden meist nur, ob ein Artefakt geschrieben wurde. Das sagt nichts über den Restore‑Pfad: Wo liegen die Schlüssel? Ist die Netzwerkroute noch offen? Sind Metadaten wie ACLs oder xattrs enthalten? Besonders MySQL kann ein scheinbar fehlerfreies Dump liefern, das nach Import logisch unbrauchbar ist (z. B. fehlende Tabellen, Collation‑Fehler oder unvollständige Binlogs für PITR – Point in Time Recovery, also Wiederherstellung bis zu einem Zeitpunkt).
Ziele, Begriffe und Fokus
Richten Sie Tests an RPO und RTO aus: RPO (Recovery Point Objective) ist der maximal tolerierbare Datenverlust; RTO (Recovery Time Objective) die erlaubte Wiederherstellungszeit. Kritische Datenpfade sind die minimalen Artefakte und Schritte, um einen Dienst kontrolliert wiederherzustellen: DB‑Schema, letzte Binlogs, Konfiguration, Zertifikate und ein kleiner Satz Referenzdaten zur Plausibilisierung.
Architekturprinzipien für tägliche Schnellrestore‑Tests
Erfolgreiche Automatisierung folgt drei Prinzipien:
- Isolierung: Restore in einer eigenen Sandbox (VM, Container, Namespace, VLAN). Keine ausgehende Verbindung zur Produktion.
- Reproduzierbarkeit: Gleiche Artefakte, gleiche Entschlüsselung, gleiche Restore‑Tools wie beim echten Notfall.
- Kostenkontrolle: Begrenzte Datenmengen, enge Timeouts, automatischer Cleanup.
End‑to‑End Design: Fünf Schritte eines Sanity‑Checks
1) Auswahl des zu testenden Artefakts
Immer das jüngste erfolgreiche Backup wählen (oder das jüngste, das RPO erfüllt). Andernfalls melden Tests fälschlich Grün, obwohl die echten Backups ausfallen.
2) Abruf und Entschlüsselung
Der Test muss dieselbe Entschlüsselungskette nutzen wie das Produktions‑Runbook (z. B. KMS/Vault/Tokens). Fehlt der Key‑Zugriff, ist der Test sinnvoll rot. Prüfen Sie auch Key‑Rotation: Wird der alte Schlüssel noch gelesen oder ist nur der neue verfügbar?
3) Restore in eine isolierte Sandbox
Nutzen Sie dedizierte Ports, Datadirs und Policies. Limits (CPU/RAM/IO) machen Restore‑Zeiten vergleichbar. Isolierung reduziert auch das Risiko, dass der Test Produktionssysteme beeinflusst.
4) Integritäts‑ und Plausibilitätschecks
Prüfen Sie mehr als Exit‑Codes: Dateihashes, Anzahl Dateien, Owner/ACLs, bei MySQL: Serverstart, erwartete Schemas/Tables und definierte Read‑Queries (COUNT, MAX(timestamp)). Dabei liefern information_schema‑Abfragen schnelle, vertrauenswürdige Signale.
5) Metriken, Logging und Cleanup
Pro Lauf speichern: Backup‑ID, Start/Endzeit, Datenmenge, Restore‑Dauer, Exit‑Codes, Detailstatus einzelner Checks. Sandbox muss auch bei Fehlern entfernt werden.
Voraussetzungen vor Automatisierung
Runbook als Quelle der Wahrheit
Die Automatisierung muss das Runbook abbilden, nicht umgekehrt. Klären Sie Reihenfolge, Ports, Secrets‑Pfad, und was zu tun ist, wenn ein Artefakt fehlt. Ein Runbook enthält auch Kommunikationswege und Verantwortlichkeiten für Eskalationen.
Identity und Secret‑Handling
Service‑Accounts für Tests brauchen Least‑Privilege, zeitlich begrenzte Tokens und Audit‑Logging. Ein unverschlüsseltes Passwortfile ist ein No‑Go. Verwenden Sie Hashicorp Vault, AWS KMS oder ein ähnliches System mit Short‑Lived‑Tokens; die Automatisierung sollte Mechanismen zum Auto‑Refresh bieten.
Netzwerkplanung
Throttling und QoS verhindern, dass Tests Backup‑Fenster anderer Systeme stören. Egress‑Blocken vermeidet versehentlichen Datenabfluss; DNS Sandboxing (eigener Resolver) verhindert, dass Tests externe Webhooks auslösen.
Datenschutz und Testdaten
Wenn produktive Daten in einer Sandbox landen, müssen Zugriffsschutz und Retention stimmen. Alternativ verwenden Sie repräsentative Teilmengen oder synthetische Golden Files. Maskierung oder Pseudonymisierung ist eine gängige Praxis, wenn personenbezogene Daten betroffen sind.
Backup-Sanity-Checks für MySQL (Fokus)
MySQL unterscheidet grob zwischen logical Backups (mysqldump; einzelne SQL‑Anweisungen) und physical Backups (z. B. Percona XtraBackup oder Block‑Snapshots). Logical Dumps sind portabler und in Schnelltests oft praktischer; physische Backups sollten jedoch rotierend abgedeckt werden, wenn diese im Ernstfall genutzt werden.
Welche MySQL‑Prüfungen sind sinnvoll?
Für tägliche Sanity‑Checks sind leichte, aussagekräftige Prüfungen ideal:
- Server‑Start in der Sandbox:
mysqldoder Docker‑Container startet und akzeptiert Verbindungen. - Schema‑Verfügbarkeit: Anzahl der erwarteten Tabellen via
information_schema. - Business‑Referenzabfragen: 3–5 vordefinierte Lesefragen (z. B. COUNT, MAX(timestamp), Prüfsummen).
- PITR‑Vorprüfung: Binlogs sind lesbar und prüfen auf Checksum‑Fehler.
- Metadaten: Berechtigungen, Stored Procedures, Events und Trigger vorhanden.
Praktische SQL‑Checks
Diese Abfragen sind schnell und aussagekräftig; passen Sie Namen an Ihre Umgebung an.
-- Anzahl Tabellen im Schema prüfen
SELECT COUNT(*) AS tables FROM information_schema.tables WHERE table_schema = 'app_db';
-- Stichprobe in einer kritischen Tabelle
SELECT COUNT(*) AS rows, MAX(updated_at) AS last_change FROM app_db.orders;
-- Server‑ und InnoDB‑Version
SELECT @@version AS mysql_version, @@innodb_version AS innodb_version;
-- Kurzer Konsistenzcheck für eine Tabelle
CHECK TABLE app_db.users QUICK;Beispiel: Schnellrestore mit mysqldump in einer Docker‑Sandbox
Ein schneller Weg, einen Dump zu prüfen, ist ein isolierter Docker‑Container mit eigener Portfreigabe:
# Start einer isolierten Testinstanz (lokal, Port 3307)
docker run --rm --name mysql-test -e MYSQL_ROOT_PASSWORD="sicheresPasswort" -d -p 3307:3306 mysql:8.0
# Import (aus dem zuvor heruntergeladenen Dump)
mysql --host=127.0.0.1 --port=3307 --user=root --password="sicheresPasswort" < /tmp/mysql-dump.sql
# Beispiel: Prüfen, ob Schema vorhanden ist
mysql --host=127.0.0.1 --port=3307 --user=root --password="sicheresPasswort" -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='app_db';"
# Stoppen des Containers nach dem Test (Cleanup wird empfohlen)
docker stop mysql-testPITR‑Vorprüfung mit mysqlbinlog
Um zu prüfen, ob die Binlogs für einen PITR‑Anwendungsfall brauchbar sind, lesen Sie die Binlogs und verifizieren Checksums. Ein lesbarer Binlog‑Stream ist ein starkes Indiz, dass eine Point‑in‑Time‑Recovery möglich ist.
# Binlog auf Lesbarkeit prüfen
mysqlbinlog --verify-binlog-checksum /path/to/binlog.000001 >/dev/null
# Beispiel: Auszugsweises Anwenden eines Binlog‑Zeitfensters
mysqlbinlog --start-datetime="2026-07-27 00:00:00" --stop-datetime="2026-07-27 01:00:00" /backup/binlogs/binlog.000001 |
mysql --host=127.0.0.1 --port=3307 --user=root --password="sicheresPasswort"Robuste Skripte: Fehlerhandling, Timeouts und Cleanup
Ein Sanity‑Runner muss auch bei Fehlern sauber aufräumen. Nutzen Sie set -euo pipefail, trap für Cleanup und definierte Exit‑Codes für automatisierte Alarmierung.
#!/usr/bin/env bash
set -euo pipefail
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)"
WORKDIR="/var/tmp/backup-sanity-${RUN_ID}"
LOGFILE="/var/log/backup-sanity/backup-sanity-${RUN_ID}.log"
mkdir -p "${WORKDIR}" "$(dirname "${LOGFILE}")"
log(){ printf '%s %sn' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*" | tee -a "${LOGFILE}"; }
cleanup(){ log "Cleanup: ${WORKDIR}"; rm -rf "${WORKDIR}" || true; }
trap cleanup EXIT
log "Starting backup sanity ${RUN_ID}"
# Backup‑ID ermitteln (Beispiel: API oder lokale Datei)
BACKUP_ID="$(cat /var/lib/backup/latest_successful_backup_id 2>/dev/null || true)"
if [[ -z "${BACKUP_ID}" ]]; then log "ERROR: no backup id"; exit 10; fi
log "Selected backup ${BACKUP_ID}"
# Beispiel: Dump herunterladen (ersetzt durch Repo‑API)
# repo-cli fetch --id "${BACKUP_ID}" --target "${WORKDIR}/mysql-dump.sql"
DUMP_FILE="${WORKDIR}/mysql-dump.sql"
if [[ ! -s "${DUMP_FILE}" ]]; then log "ERROR: dump missing"; exit 21; fi
# Start Test‑DB (lokal, Port 3307) - hier als Beispiel mit systemd‑Unit oder docker
# Weiterer Code: Import, Prüfungen, Metrikaufzeichnung
log "Import complete, running SQL checks"
Erweiterte MySQL‑Troubleshooting bei Restore‑Fehlern
Charakterset- und Collation-Probleme
Symptom: Import gelingt, aber Texte sind fehlerhaft oder Vergleiche schlagen fehl. Ursache: Unterschiedliche Zeichensatz‑Einstellungen beim Dump und beim Zielserver. Prüfen Sie SHOW VARIABLES LIKE 'character_set%'; und verwenden Sie beim Dump --default-character-set=utf8mb4.
Fehlende Binlogs oder GTID‑Inkompatibilitäten
Wenn Ihre Produktivumgebung GTIDs nutzt, Ihr Testserver nicht, kann das Anwenden der Binlogs fehlschlagen. Prüfen Sie GTID‑Status und setzen Sie entsprechende Optionen beim Import (z. B. SET @@SESSION.SQL_LOG_BIN=0; für nicht‑replizierende Tests).
InnoDB‑Tablespace/LSN‑Probleme bei physischen Backups
Physische Backups (XtraBackup) müssen vorbereitet werden (xtrabackup --prepare), damit die InnoDB‑Logs konsistent sind. Vergleichen Sie LSN (Log Sequence Number) in the Backup‑Manifest mit der laufenden Server‑LSN; ein Mismatch kann den Serverstart verhindern.
# XtraBackup vorbereiten
xtrabackup --prepare --target-dir=/backup/dir
# LSN anzeigen (Beispiel aus Backup‑Log)
grep -i 'innodb_lsn' /backup/dir/xtrabackup_info || true
Monitoring, Alarmierung und Trendanalyse
Erfassen Sie Metriken pro Lauf:
- Success/Failure (binary)
- Restore‑Duration (Sekunden)
- Datenmenge übertragen
- Failure‑Kategorie (Key, Fetch, Import, Validation)
Visualisieren Sie diese Metriken in Grafana/Prometheus oder Ihrem Monitoring‑Stack. Legen Sie Eskalationsregeln fest: Warnung bei 1 Fehler, Ticket bei 2 aufeinanderfolgenden Fehlern, Incident bei 3. Analysieren Sie Trends: steigende Restore‑Dauer kann auf Storage‑Degradation oder Netzwerkprobleme hinweisen.
Stolperfallen, die häufig übersehen werden
1) Immutable Backups vs. Key Rotation
Immutable Backups schützen vor Löschung, aber wenn Schlüssel rotiert werden und alte Schlüssel nicht mehr zugreifbar sind, sind die Backups nutzlos. Tests müssen Key‑Weg und historische Zugriffe validieren.
2) Storage‑Quotas und partielle Artefakte
Manche Backup‑Jobs schreiben bis eine Quota erreicht ist und brechen ab, ohne Fehlercode zu liefern. Prüfen Sie Dateigrößen und Vollständigkeit via Hashes.
3) Hidden Meta‑Excludes
Automatisierte Excludes (z. B. über .backupignore) können kritische Dateien auslassen. Sanity‑Checks sollten solche Excludes überwachen und gelegentlich vollständige Backups prüfen.
Rückfallstrategie: Was bei roten Tests zu tun ist
Sofortmaßnahmen (erste 30–60 Minuten)
- Logauswertung: Runner, Backup‑ID, Fehlermeldungen
- Repeat auf anderem Runner/Region, um Runner‑seitige Probleme auszuschließen
- Key‑Store und Repository‑Erreichbarkeit prüfen
Stabilisierung am selben Tag
- Letztes bekannt gutes Backup markieren und ggf. als bevorzugte Quelle kennzeichnen
- Vorübergehende Anpassung der Backup‑Jobs (z. B. Vollbackup statt inkrementell)
- Kommunikation an betroffene Teams mit Massnahmen und erwarteter Dauer
Nachhaltige Korrektur
- Runbook anpassen, Checks erweitern (z. B. zusätzliche Checksums, Binlog‑Gestüpp)
- Root‑Cause‑Analyse: Warum scheiterte der Test? Infrastruktur? Key‑Rotation? Repo‑Bug?
- Regelmäßige DR‑Übungen in größerem Umfang planen
Operationalisierung: Rollen, Verantwortungen, Dokumentation
Sanity‑Checks fungieren als klarer, messbarer Vertrag zwischen Backup‑, DB‑ und Plattformteams: Artefakt‑Lieferung, Restore‑Schritte und Sandbox‑Betrieb sind getrennte Verantwortlichkeiten mit definierten Metriken. Halten Sie folgende Punkte dokumentiert:
- Owner der Test‑Runner und ihrer Berechtigungen
- Pfad zu Keys/Secrets und Rotationstermine
- Kontaktliste bei Prüfungsfehlern
- Offizielle Versionierung des Runbooks
Beispiel‑Checkliste für die tägliche Automatisierung
- Runner startet und holt neueste Backup‑ID
- Abruf & Entschlüsselung erfolgreich
- Restore in Sandbox innerhalb definierter Timeouts
- 3–5 vordefinierte SQL‑Checks bestehen
- PITR‑Vorprüfung: Binlogs lesbar
- Metadaten (ACLs, xattrs, Procs) Stichprobe erfolgreich
- Report erstellt, Metriken veröffentlicht
- Cleanup durchgeführt
Fazit
Regelmäßige, automatisierte Backup‑Sanity‑Checks erhöhen die Wahrscheinlichkeit, im Incident tatsächlich wiederherstellen zu können. Starten Sie klein (Subset‑Restore, wenige robuste Checks), isolieren und messen Sie konsequent. Besonders bei MySQL gilt: Ein Restore ist erst dann „grün“, wenn die Instanz startet und definierte Plausibilitätsabfragen sinnvolle Ergebnisse liefern – nicht allein, wenn das Backup‑Tool einen Erfolg meldet. Dokumentieren Sie Runbooks, automatisieren Sie Metriken und bauen Sie Eskalationspfade. So verhindern Sie, dass Backups nur Artefakte bleiben und im Ernstfall nicht nutzbar sind.
Backup‑Sanity‑Checks in CI/CD und Infrastruktur als Code
Binden Sie Backup‑Sanity‑Checks in Ihre Deployment‑Pipelines ein: Ein fehlgeschlagener Schnellrestore sollte Deployments blockieren oder ein schnelles Rollback triggern. Legen Sie dazu eine klare Kompatibilitätsmatrix fest (Backup‑Tool‑Version, MySQL‑Major‑Version, Dump‑Format). Nutzen Sie Infrastruktur als Code, um die Sandbox reproduzierbar zu provisionieren (Terraform/Ansible), damit Restore‑Fehler nicht auf flüchtige Testumgebungen zurückzuführen sind.
Speichern Sie pro Test ein Manifest (Backup‑ID, Key‑Version, Tool‑Version, Checksumme) – das erleichtert Root‑Cause‑Analysen und Reproduzierbarkeit. Automatisieren Sie Ticket‑Erzeugung bei Fehlschlägen und messen Sie SLAs für Sanity‑Checks (z. B. Zeit bis Fehlerbestätigung). Planen Sie regelmäßige Full‑DR‑Übungen zusätzlich zu täglichen Schnelltests: nur so prüfen Sie Abhängigkeiten und organisatorische Abläufe, die automatisierte Checks nicht abbilden können.
Für dieses Thema sind auch Schnellrestore-Test und Restore-Validierung wichtig. Der Beitrag ordnet diese Aspekte verständlich ein und zeigt, worauf es im Alltag ankommt.