Point-in-Time Recovery mit Binlogs durchführen
AI generated
InnoDB
SQL
MySQL · Backup & Recovery · Binary Logging
Point-in-Time Recovery mit Binlogs durchführen
vom Basis-Backup bis zur exakten Sekunde vor dem Fehler

Ein tägliches Backup allein rettet nur den Stand von Mitternacht. Point-in-Time Recovery kombiniert ein Basis-Backup mit dem gezielten Replay von Binlogs und stellt eine MySQL-Datenbank bis zur letzten korrekten Transaktion wieder her, direkt vor einem fehlerhaften DELETE oder DROP.

18 Min. Lesezeit mysqlbinlog · Binary Logging · GTID MySQL 8.0 · Percona Server · MariaDB

1. Was Point-in-Time Recovery leistet

Point-in-Time Recovery löst ein Problem, das ein reines Voll-Backup nicht lösen kann: den Zustand einer Datenbank exakt zu einem beliebigen Zeitpunkt zwischen zwei Backups wiederherzustellen. Wenn ein fehlerhaftes DELETE-Statement um 14:37 Uhr versehentlich zehntausend Bestellungen löscht, hilft ein Backup von Mitternacht nur bedingt: alle Transaktionen zwischen Mitternacht und dem Fehler wären verloren. Point-in-Time Recovery schließt genau diese Lücke, indem ein Basis-Backup mit den seit dem Backup geschriebenen Binlogs kombiniert wird.

Der Mechanismus dahinter ist einfach beschrieben, aber in der Praxis anspruchsvoll: zuerst wird das letzte konsistente Backup vollständig eingespielt, danach werden alle Binlog-Events ab dem Backup-Zeitpunkt bis kurz vor den Fehler erneut angewendet. Diese Kombination aus Restore und Replay ist der Kern jeder Point-in-Time Recovery-Strategie und funktioniert unabhängig davon, ob die Datenbank Teil einer Magento-Installation, einer Symfony-Anwendung oder eines beliebigen anderen Systems ist. Wer diesen Ablauf nicht vorher geübt hat, verliert im Ernstfall wertvolle Zeit und riskiert zusätzliche Fehler unter Druck.

2. Binary Logging korrekt aktivieren

Ohne aktiviertes Binary Logging ist Point-in-Time Recovery von vornherein unmöglich, weil schlicht keine Aufzeichnung der Änderungen seit dem letzten Backup existiert. Binary Logging wird über die Konfigurationsdatei aktiviert und schreibt jede datenverändernde Operation als Event in eine Sequenz von Binlog-Dateien. Wichtig ist dabei die Wahl des Binlog-Formats: ROW zeichnet die tatsächlich geänderten Zeilen auf und ist für eine präzise Wiederherstellung deutlich zuverlässiger als STATEMENT, das nur die ausgeführte SQL-Anweisung speichert.

Ebenso entscheidend ist die Aufbewahrungsdauer der Binlogs, gesteuert über binlog_expire_logs_seconds. Wird dieser Wert zu niedrig gesetzt, werden alte Binlogs gelöscht, bevor das nächste Basis-Backup entstanden ist, und eine Point-in-Time Recovery über den gelöschten Zeitraum wird unmöglich. Als Faustregel gilt: die Aufbewahrung muss mindestens die doppelte Backup-Intervall-Dauer abdecken, damit auch bei einem verzögerten Backup-Lauf noch genug Historie vorhanden ist.


# my.cnf: Binary Logging für Point-in-Time Recovery aktivieren
[mysqld]
server-id               = 101
log_bin                 = /var/lib/mysql-binlogs/binlog
binlog_format            = ROW
binlog_row_image         = FULL
binlog_expire_logs_seconds = 604800   # 7 Tage Aufbewahrung
max_binlog_size          = 512M
sync_binlog               = 1
innodb_flush_log_at_trx_commit = 1

# GTID für robustere Point-in-Time Recovery (empfohlen)
gtid_mode                = ON
enforce_gtid_consistency = ON
log_slave_updates        = ON

3. Basis-Backup als Ausgangspunkt erstellen

Jede Point-in-Time Recovery beginnt mit einem konsistenten Basis-Backup, dessen exakte Binlog-Position bekannt sein muss. Ohne diese Startposition weiß der Recovery-Prozess nicht, ab welchem Event die Binlogs erneut angewendet werden sollen, und riskiert entweder doppelte Anwendung bereits gesicherter Änderungen oder eine Lücke im wiederhergestellten Datenbestand. Percona XtraBackup schreibt diese Position automatisch in die Datei xtrabackup_binlog_info, mysqldump mit der Option --master-data=2 in den Dump-Header als Kommentar.

In der Praxis empfiehlt sich ein tägliches physisches Backup mit XtraBackup, weil es ohne langes Sperren der Tabellen auskommt und bei großen Datenbanken deutlich schneller wiederhergestellt werden kann als ein logisches mysqldump-Backup. Die Kombination aus täglichem Basis-Backup und kontinuierlich geschriebenen Binlogs reduziert das maximale Datenverlustfenster auf die Zeit zwischen zwei Binlog-Flushes, in der Praxis oft nur wenige Sekunden.


# Basis-Backup mit Percona XtraBackup erstellen
xtrabackup --backup \
  --target-dir=/backup/base/$(date +%F) \
  --user=backup_user --password="$BACKUP_PW"

# Binlog-Position des Backups anzeigen (wichtig für Point-in-Time Recovery)
cat /backup/base/$(date +%F)/xtrabackup_binlog_info
# Ausgabe z. B.: binlog.000042    157      3E11FA47-...:1-928472

# Backup vorbereiten (Redo-Log anwenden)
xtrabackup --prepare --target-dir=/backup/base/$(date +%F)

4. Binlog-Formate und Events verstehen

Ein Binlog besteht aus einer Sequenz einzelner Events: Query-Events, Row-Events, Xid-Events für Transaktionsabschlüsse und Rotate-Events beim Wechsel in eine neue Binlog-Datei. Für Point-in-Time Recovery ist entscheidend, dass jedes Event entweder über eine Byte-Position innerhalb einer Datei oder, bei aktiviertem GTID, über eine global eindeutige Transaktions-ID adressierbar ist. Beide Adressierungsarten erlauben es, das Replay exakt vor einem bestimmten Event zu stoppen.

Mit SHOW BINARY LOGS und SHOW BINLOG EVENTS IN lassen sich die vorhandenen Dateien und deren Inhalt direkt in der MySQL-Shell inspizieren, bevor mysqlbinlog für die eigentliche Recovery eingesetzt wird. Das ist besonders hilfreich, um vor einem Recovery-Vorgang zu prüfen, in welcher Datei und an welcher Position sich das fehlerhafte Statement befindet, ohne bereits die vollständige Textausgabe von mysqlbinlog durchsuchen zu müssen.


-- Vorhandene Binlog-Dateien auflisten
SHOW BINARY LOGS;

-- Events einer bestimmten Binlog-Datei inspizieren
SHOW BINLOG EVENTS IN 'binlog.000042' LIMIT 20;

-- Aktuelle Schreibposition des Servers ermitteln
SHOW MASTER STATUS;
-- File: binlog.000045 | Position: 738291 | Executed_Gtid_Set: 3E11FA47-...:1-931205

5. mysqlbinlog: Inhalte inspizieren und filtern

Das Kommandozeilenwerkzeug mysqlbinlog übersetzt die binären Binlog-Dateien in lesbares SQL und ist das zentrale Werkzeug jeder Point-in-Time Recovery. Mit den Optionen --start-datetime und --stop-datetime lässt sich ein Zeitfenster eingrenzen, mit --start-position und --stop-position ein exakter Byte-Bereich. Für die eigentliche Fehlersuche vor einer Recovery ist die Kombination mit grep praktisch, um die genaue Position eines fehlerhaften Statements zu finden, bevor der Stop-Punkt final festgelegt wird.

Ein häufiger Fehler ist, das Zeitfenster zu grob zu wählen und dadurch entweder den fehlerhaften Befehl versehentlich mit zu replayen oder zu viele gutartige Transaktionen wegzulassen. Deshalb empfiehlt sich immer zuerst ein Trockenlauf mit reiner Textausgabe in eine Datei, die manuell durchsucht wird, bevor das Ergebnis tatsächlich gegen die Datenbank ausgeführt wird. Erst wenn die exakte Stop-Position bestätigt ist, folgt der produktive Replay-Schritt.


# Binlog-Inhalt als lesbares SQL ausgeben und nach dem Fehler suchen
mysqlbinlog --base64-output=decode-rows -v \
  /var/lib/mysql-binlogs/binlog.000045 > /tmp/binlog_dump.sql

grep -n -B5 "DELETE FROM \`sales_order\`" /tmp/binlog_dump.sql

# Gezielt bis kurz vor den fehlerhaften Befehl extrahieren
mysqlbinlog --start-datetime="2026-07-23 14:00:00" \
  --stop-datetime="2026-07-23 14:36:59" \
  /var/lib/mysql-binlogs/binlog.000045 > /tmp/replay_safe.sql

6. Der Recovery-Ablauf im Detail

Der vollständige Ablauf einer Point-in-Time Recovery gliedert sich in drei klar getrennte Phasen. In der ersten Phase wird das vorbereitete Basis-Backup auf einen separaten Datenverzeichnis-Pfad kopiert und der MySQL-Server mit diesem Datenbestand gestartet, idealerweise auf einer isolierten Instanz und nicht direkt auf dem Produktionsserver. In der zweiten Phase wird mit mysqlbinlog der Bereich von der im Backup vermerkten Startposition bis zur ermittelten Stop-Position extrahiert und gegen diese wiederhergestellte Instanz ausgeführt.

In der dritten Phase folgt die Verifikation: stichprobenartige Abfragen prüfen, ob die erwarteten Datensätze wieder vorhanden sind und die fehlerhafte Operation tatsächlich nicht mehr enthalten ist. Erst nach erfolgreicher Verifikation wird die wiederhergestellte Instanz zur neuen Produktionsdatenbank, entweder durch Umschalten der Anwendungskonfiguration oder durch selektiven Export der betroffenen Tabellen zurück in die laufende Produktionsdatenbank, falls nur ein Teilbereich betroffen war.

7. GTID- versus positionsbasierte Recovery

Vor MySQL 5.6 und ohne aktiviertes GTID musste jede Point-in-Time Recovery mit exakten Datei-Byte-Positionen arbeiten, was bei mehreren Binlog-Dateien und Rotationen fehleranfällig ist. Mit aktiviertem gtid_mode = ON erhält jede Transaktion eine global eindeutige ID, unabhängig von Dateigrenzen. mysqlbinlog unterstützt dann Optionen wie --exclude-gtids, um gezielt eine einzelne problematische Transaktion aus dem Replay auszuschließen, ohne das gesamte Zeitfenster manuell eingrenzen zu müssen.

GTID-basierte Recovery ist besonders in Replikationssetups mit mehreren Servern von Vorteil, weil die Transaktions-ID auf allen Knoten identisch bleibt und ein Replay auf einem anderen Server als dem ursprünglichen Master keine Positions-Umrechnung erfordert. In der Praxis empfiehlt sich GTID daher für jede neue MySQL-Installation, während positionsbasierte Recovery vor allem in Alt-Systemen ohne GTID noch relevant bleibt.

Kriterium Positionsbasiert GTID-basiert
Adressierung Datei plus Byte-Offset Global eindeutige Transaktions-ID
Fehleranfälligkeit Hoch bei Rotationen und mehreren Servern Gering, ID bleibt serverübergreifend gleich
Einzelne Transaktion ausschließen Nur über manuelle Positionsberechnung --exclude-gtids direkt nutzbar
Replay auf anderem Server Erfordert Positions-Umrechnung Ohne Anpassung möglich
Verfügbarkeit Immer verfügbar Ab MySQL 5.6 mit gtid_mode = ON

8. Recovery-Drill Schritt für Schritt

Ein Recovery-Plan, der nie geübt wurde, ist im Ernstfall nur eine Theorie. Ein regelmäßiger Point-in-Time Recovery-Drill auf einer Test-Instanz deckt Lücken auf, bevor sie im Ernstfall teuer werden: fehlende Berechtigungen für den Backup-User, zu kurze Binlog-Aufbewahrung, veraltete Runbooks oder schlicht ein Team, das den Ablauf noch nie unter Zeitdruck durchgespielt hat. Ein guter Drill simuliert bewusst einen fehlerhaften DELETE-Befehl, misst die Zeit bis zur vollständigen Wiederherstellung und dokumentiert jeden Schritt.

Die folgende Sequenz zeigt einen vollständigen Drill von der Fehlersimulation bis zur Verifikation, wie er sich in einer Staging-Umgebung monatlich wiederholen lässt. Wichtig ist, das Ergebnis jedes Drills schriftlich festzuhalten, inklusive der tatsächlich benötigten Zeit, damit sich die Recovery Time Objective realistisch einschätzen lässt und nicht auf Annahmen beruht.


# Kompletter Recovery-Drill auf einer isolierten Test-Instanz
set -euo pipefail

# 1. Fehler simulieren (nur auf der Test-Instanz!)
mysql -e "DELETE FROM sales_order WHERE created_at < '2026-07-20';"

# 2. Basis-Backup auf Test-Datenverzeichnis kopieren
rsync -a /backup/base/2026-07-23/ /var/lib/mysql-drill/
chown -R mysql:mysql /var/lib/mysql-drill/

# 3. Test-Instanz mit wiederhergestelltem Basis-Backup starten
mysqld --datadir=/var/lib/mysql-drill --port=3307 --socket=/tmp/drill.sock &

# 4. Binlogs bis kurz vor den simulierten Fehler replayen
mysqlbinlog --start-position=157 --stop-datetime="2026-07-23 14:36:59" \
  /var/lib/mysql-binlogs/binlog.000045 | \
  mysql --socket=/tmp/drill.sock -u root

# 5. Verifikation und Zeitmessung dokumentieren
mysql --socket=/tmp/drill.sock -e "SELECT COUNT(*) FROM sales_order;"

9. Fallstricke und Performance-Aspekte

Der häufigste Fallstrick bei Point-in-Time Recovery ist eine Binlog-Aufbewahrung, die kürzer ist als der Abstand zwischen zwei Basis-Backups. Wird ein Backup übersprungen, etwa wegen eines vollen Datenträgers, und die Binlogs sind bereits rotiert, entsteht eine unwiederbringliche Lücke. Ein zweiter Fallstrick ist das Fehlen von log_slave_updates auf Replikaten, wodurch auf einem Replika replizierte Änderungen nicht erneut in dessen eigene Binlogs geschrieben werden und dort für eine Recovery fehlen.

Bei sehr großen Binlog-Mengen kann das Replay selbst zur Engpassquelle werden, weil mysqlbinlog die Events sequenziell und einzeln an den Server sendet. Für sehr lange Zeitfenster empfiehlt sich, das Replay in mehreren kleineren Abschnitten durchzuführen und zwischendurch Checkpoints zu prüfen, statt einen einzigen mehrstündigen Lauf zu riskieren, der bei einem Abbruch von vorn beginnen müsste. Auch innodb_flush_log_at_trx_commit und sync_binlog sollten in Produktion auf sicheren Werten stehen, sonst kann selbst das Binlog Lücken gegenüber tatsächlich committeten Transaktionen aufweisen.

Mironsoft

MySQL-Backup, Recovery und Betriebssicherheit für produktive Datenbanken

Point-in-Time Recovery, die im Ernstfall tatsächlich funktioniert?

Wir richten Binary Logging, Backup-Strategie und Recovery-Runbooks für eure MySQL-Umgebung ein und üben den Ablauf gemeinsam mit eurem Team, bevor der erste echte Vorfall eintritt.

Backup-Konzeption

Basis-Backups, Binlog-Retention und Aufbewahrungsfristen passend zum Datenvolumen auslegen

Recovery-Runbooks

Dokumentierte, getestete Abläufe für Point-in-Time Recovery statt Improvisation im Ernstfall

Recovery-Drills

Regelmäßige Wiederherstellungsübungen mit Zeitmessung und schriftlicher Auswertung

10. Zusammenfassung

Point-in-Time Recovery schließt die Lücke, die ein reines Backup offen lässt: die Wiederherstellung bis zur letzten korrekten Transaktion vor einem Fehler. Voraussetzung ist aktiviertes Binary Logging im ROW-Format mit ausreichender Aufbewahrungsdauer, ein regelmäßiges Basis-Backup mit dokumentierter Binlog-Startposition und die Fähigkeit, mysqlbinlog gezielt für ein bestimmtes Zeitfenster oder eine bestimmte GTID einzusetzen.

Der größte Hebel liegt nicht in der Technik allein, sondern in der Übung: ein Recovery-Ablauf, der monatlich als Drill durchgespielt wird, deckt fehlende Berechtigungen, zu kurze Aufbewahrungsfristen und veraltete Dokumentation auf, bevor ein echter Vorfall die Datenbank betrifft. GTID-basierte Recovery reduziert dabei zusätzlich die Fehleranfälligkeit gegenüber rein positionsbasierten Abläufen.

Point-in-Time Recovery mit Binlogs: Das Wichtigste auf einen Blick

Binary Logging

ROW-Format, ausreichende binlog_expire_logs_seconds und aktiviertes GTID sind die technische Grundvoraussetzung.

Basis-Backup

Tägliches physisches Backup mit dokumentierter Binlog-Startposition, etwa via XtraBackup.

mysqlbinlog

Zeitfenster oder GTID gezielt eingrenzen, immer erst als Textausgabe prüfen, dann replayen.

Drill statt Theorie

Monatliche Übung auf Test-Instanz mit Zeitmessung deckt Lücken vor dem Ernstfall auf.

11. FAQ: Point-in-Time Recovery mit Binlogs

1Was ist Point-in-Time Recovery in MySQL?
Point-in-Time Recovery ist die Wiederherstellung einer Datenbank bis zu einem exakten Zeitpunkt zwischen zwei Backups, indem ein Basis-Backup eingespielt und anschließend die seither geschriebenen Binlogs bis kurz vor einen Fehler erneut angewendet werden.
2Reicht ein tägliches Backup nicht auch so aus?
Ein tägliches Backup allein rettet nur den Stand des Backup-Zeitpunkts. Alle Transaktionen danach bis zum Fehler gehen ohne Binlogs verloren. Point-in-Time Recovery schließt genau diese Lücke durch das Replay der Binlogs.
3Welches Binlog-Format sollte ich für Point-in-Time Recovery nutzen?
ROW ist die empfohlene Wahl, weil es die tatsächlich geänderten Zeilen aufzeichnet statt der ausgeführten SQL-Anweisung und dadurch bei nicht-deterministischen Funktionen präziser reproduzierbar ist.
4Wie lange sollten Binlogs aufbewahrt werden?
Mindestens das Doppelte des Backup-Intervalls. Bei täglichen Backups sind 7 Tage Aufbewahrung eine gängige Praxis, damit auch bei einem verzögerten oder fehlgeschlagenen Backup-Lauf noch genug Historie vorhanden ist.
5Was ist der Unterschied zwischen positionsbasierter und GTID-basierter Recovery?
Positionsbasiert adressiert Events über Datei und Byte-Offset, was bei mehreren Servern fehleranfällig ist. GTID vergibt jeder Transaktion eine global eindeutige ID, die serverübergreifend gleich bleibt und gezieltes Ausschließen einzelner Transaktionen erlaubt.
6Kann ich eine einzelne fehlerhafte Transaktion überspringen, ohne den Rest zu verlieren?
Mit GTID ja, über die Option --exclude-gtids von mysqlbinlog. Ohne GTID muss das Zeitfenster manuell so gewählt werden, dass die fehlerhafte Position ausgeschlossen bleibt, was fehleranfälliger ist.
7Sollte Point-in-Time Recovery direkt auf dem Produktionsserver durchgeführt werden?
Nein. Empfohlen ist eine isolierte Test-Instanz, auf der das Ergebnis vor der Übernahme in Produktion verifiziert werden kann. So wird ein zweiter Fehler während der Recovery vermieden.
8Wie finde ich die exakte Stop-Position vor einem fehlerhaften Befehl?
Mit mysqlbinlog und --verbose die betroffene Binlog-Datei als Text ausgeben und mit grep nach dem fehlerhaften Statement suchen. Die davorliegende Position oder der Zeitstempel wird als Stop-Punkt verwendet.
9Was passiert, wenn die Binlogs bereits rotiert und gelöscht wurden?
Dann endet die maximale Recovery-Tiefe am ältesten noch vorhandenen Basis-Backup ohne Binlog-Replay. Deshalb muss die Aufbewahrungsdauer immer länger sein als das Backup-Intervall.
10Wie oft sollte ein Recovery-Drill durchgeführt werden?
Monatlich ist ein sinnvoller Rhythmus für produktionskritische Datenbanken. Der Drill deckt fehlende Berechtigungen, zu kurze Aufbewahrung und veraltete Runbooks auf, bevor ein echter Vorfall eintritt.