# Database Recovery: Rettung von PostgreSQL & MySQL/MariaDB
TL;DR / Management Summary Ein einfacher Datei-Restore (Artikel 638) reicht bei Datenbanken oft nicht aus, da sie zum Zeitpunkt des Backups inkonsistent gewesen sein könnten. Wir nutzen native Recovery-Tools der Datenbankhersteller. Das ultimative Ziel ist das Point-in-Time Recovery (PITR): Die Fähigkeit, eine Datenbank exakt auf den Zustand von z.B. 14:02 Uhr heute zurückzusetzen, indem wir das letzte Full-Backup mit den seither geschriebenen Write-Ahead-Logs (WAL) oder Binary Logs kombinieren.
# 1. Wiederherstellungs-Typen
Vom Dump zum Log.
- Logical Restore (SQL Dump): Einspielen von
.sqlDateien.- Vorteil: Sehr stabil, plattformübergreifend.
- Nachteil: Langsam bei großen Datenmengen (GB/TB Bereich).
- Physical Restore (Binary): Zurückkopieren der rohen Datenbank-Dateien.
- Vorteil: Extrem schnell.
- Voraussetzung: Identische Datenbankversion.
- Point-in-Time Recovery (PITR): Wiederherstellung auf eine spezifische Sekunde.
# 2. PostgreSQL Recovery
Die WAL-Magie.
PostgreSQL schreibt jede Änderung zuerst in das Write-Ahead-Log (WAL).
# Der PITR Prozess
- Stoppen des Datenbank-Dienstes.
- Wiederherstellen des letzten Base-Backups (physisch).
- Konfigurieren der
recovery.conf(oderpostgresql.auto.confin neueren Versionen):
restore_command = 'cp /mnt/archive/%f %p'
recovery_target_time = '2023-05-15 14:02:00'
- Dienst starten. Postgres liest alle Logs bis zum Zielzeitpunkt ein und geht dann in den Read-Write Modus.
# 3. MySQL / MariaDB Recovery
Binary Logs und MyISAM/InnoDB.
# MySqldump einspielen
mysql -u root -p meine_datenbank < backup.sql
# Point-in-Time Recovery (via binlog)
MySQL speichert Änderungen in Binary Logs.
- Restore des letzten Dumps.
- Anwenden der Änderungen seit dem Dump:
mysqlbinlog /var/lib/mysql/binlog.000* --start-datetime="2023-05-15 00:00:00" | mysql -u root -p
# 4. Day-2 Operations: Datenbank-Integritätsprüfung
Ist das Backup wirklich gesund?
Nach jedem Restore sollten Sie einen logischen Check durchführen:
- MySQL:
mysqlcheck -u root -p --all-databases --check. - PostgreSQL:
VACUUM ANALYZE.
# 5. Troubleshooting & “War Stories”
Wenn die Tabelle ‘locked’ ist.
# Top 3 Fehlerbilder
-
Symptom: “Table ‘xyz’ is marked as crashed”.
- Ursache: Harter Power-Off des Servers ohne sauberes Datenbank-Shutdown.
- Lösung:
REPAIR TABLE xyz(nur MyISAM) oder InnoDB-Recovery-Mode in dermy.cnfaktivieren.
-
Symptom: Restore dauert Tage.
- Ursache: Indizes werden beim Import mühsam Zeile für Zeile aufgebaut.
- Fix: Indizes vor dem Import deaktivieren und danach in einem Rutsch neu erstellen (
Knoten-Modus).
-
Symptom: “Duplicate Key” Fehler beim PITR.
- Ursache: Das Ziel-System war nicht komplett leer vor dem Restore.
# “War Story”: Der “Fatale” Update-Befehl
Ein Junior-Admin führte ein UPDATE users SET status = 'deleted' ohne WHERE-Klausel aus. 100.000 User-Accounts waren schlagartig deaktiviert. Das letzte Backup war 12 Stunden alt.
Die Rettung: Da der Server im Archiv-Mode (WAL) lief, konnten wir via Point-in-Time Recovery eine Kopie der Datenbank auf einem anderen Proxmox-Node erstellen und den Zustand von 1 Minute vor dem fatalen Befehl wiederherstellen.
Lehre: Betreiben Sie produktive Datenbanken immer im Log-Archivierungsmodus. Ein tägliches Backup reicht bei menschlichen Fehlern nicht aus.
# 6. Monitoring & Reporting
Status der Transaktionen.
# Backup-Freshness Monitoring
Überwachen Sie das Alter des letzten erfolgreichen Logs-Backups.
- KPI:
db_log_delay_seconds. Wenn dieser Wert > 15 Min steigt, ist Ihr PITR-Fenster gefährdet.
# 7. Fazit & Empfehlung
Datenbank-Recovery erfordert Übung und die richtigen Tools.
- Empfehlung: Nutzen Sie Barman für PostgreSQL oder Percona XtraBackup für MySQL für professionelle, physische Sicherungen.
- Wichtig: Testen Sie den Restore-Prozess monatlich in einer Test-Instanz. Eine Datenbank, die sich nicht wiederherstellen lässt, ist nur teurer Datenmüll.
# Anhang: Cheatsheet
| Aufgabe | PostgreSQL | MySQL |
|---|---|---|
| Logical Dump | pg_dump db > file |
mysqldump db > file |
| Restore Dump | psql db < file |
mysql db < file |
| Config Pfad | /etc/postgresql/X/main/ |
/etc/mysql/my.cnf |
| Log Check | pg_controldata |
mysqlbinlog |