Redo Log und Crash Recovery: wie InnoDB Datenverlust verhindert
AI generated
InnoDB
SQL
MySQL · InnoDB · Durability
Redo Log und Crash Recovery
wie InnoDB Datenverlust verhindert

Wenn ein MySQL-Server mitten in einem Schreibvorgang abstürzt, entscheidet das Redo Log darüber, ob Daten verloren gehen oder ob die Datenbank sich beim nächsten Start automatisch selbst repariert. Das Verständnis von Write-Ahead Logging, Checkpoint-Mechanik und Log-Sizing ist deshalb keine akademische Übung, sondern die Grundlage für belastbare Produktionsdatenbanken. Dieser Artikel erklärt den kompletten Mechanismus mit echten Konfigurationsbeispielen.

19 Min. Lesezeit innodb_log_file_size · Checkpoint · LSN MySQL 8.0 · MariaDB 10.x

1. Was das Redo Log leistet: Write-Ahead Logging

Das Redo Log ist das Herzstück der Crash-Sicherheit von InnoDB und setzt das Prinzip des Write-Ahead Logging um. Bevor InnoDB eine Änderung tatsächlich in die betroffene Datenseite im Buffer Pool schreibt und diese Seite später auf die Platte flusht, wird die Änderung zunächst als kompakter Eintrag im Redo Log persistiert. Dieser Eintrag beschreibt nicht den kompletten neuen Zustand der Seite, sondern nur die physische Änderung selbst, was das Schreiben ins Redo Log sehr schnell macht, weil es sich um sequentielle, kleine Schreibvorgänge handelt statt um wahllose Zugriffe auf verstreute Datenseiten.

Der entscheidende Vorteil dieses Ansatzes: Sobald eine Transaktion committet, muss nicht die eigentliche Datenseite auf die Platte geschrieben werden, sondern nur der zugehörige Redo-Log-Eintrag. Das Schreiben der Datenseiten selbst kann InnoDB später, gebündelt und effizienter, im Hintergrund erledigen. Stürzt der Server danach ab, bevor die Datenseite tatsächlich persistiert wurde, rekonstruiert InnoDB die Änderung beim nächsten Start aus dem Redo Log. Genau dieser Mechanismus verhindert, dass committete Transaktionen bei einem Absturz verloren gehen.

2. Aufbau: Log Buffer, Log Files und LSN

Bevor ein Eintrag ins Redo Log auf die Platte geschrieben wird, landet er zunächst im Log Buffer, einem Speicherbereich im RAM, gesteuert über innodb_log_buffer_size. Der Log Buffer sammelt mehrere Änderungen und schreibt sie gebündelt auf die Platte, was die Anzahl der teuren I/O-Operationen reduziert. Jeder Eintrag im Redo Log erhält eine fortlaufende Log Sequence Number, kurz LSN, die als eindeutiger Zeitstempel für jede physische Änderung an der Datenbank dient und beim Crash Recovery als Referenzpunkt genutzt wird.

Physisch besteht das Redo Log aus mehreren Dateien, deren Anzahl und Größe über innodb_redo_log_capacity in aktuellen MySQL-Versionen gesteuert wird, in älteren Versionen über die getrennten Parameter innodb_log_file_size und innodb_log_files_in_group. Diese Dateien werden zirkulär beschrieben: Ist die letzte Datei voll, beginnt InnoDB wieder am Anfang der ersten Datei, vorausgesetzt die dort enthaltenen Änderungen wurden bereits über einen Checkpoint in die eigentlichen Datenseiten übernommen.


-- Inspect current redo log configuration
SHOW VARIABLES LIKE 'innodb_redo_log%';
SHOW VARIABLES LIKE 'innodb_log_buffer_size';

-- Current LSN position and checkpoint LSN
SHOW ENGINE INNODB STATUS\G
-- Look for the LOG section:
-- Log sequence number          123456789012
-- Log flushed up to            123456789012
-- Last checkpoint at           123456780000

3. innodb_log_file_size richtig dimensionieren

Die Größe des Redo Log beeinflusst direkt zwei gegenläufige Faktoren: Schreibperformance und Recovery-Zeit nach einem Absturz. Ein größeres Redo Log erlaubt InnoDB, Datenseiten seltener auf die Platte zu flushen, weil mehr Änderungen im Log gesammelt werden können, bevor ein Checkpoint erzwungen werden muss. Das verbessert die Schreibperformance bei schreiblastigen Workloads erheblich, da weniger zufällige I/O-Operationen für das Flushen der Datenseiten nötig sind. Der Nachteil: Ein größeres Redo Log bedeutet potenziell mehr ungesicherte Änderungen, die beim Crash Recovery erneut angewendet werden müssen, was die Downtime nach einem Absturz verlängert.

Für die meisten Produktionssysteme ist eine Gesamtgröße des Redo Log zwischen 1 und 4 GB ein solider Ausgangspunkt, bei sehr schreiblastigen Systemen mit vielen großen Transaktionen können auch 8 GB oder mehr sinnvoll sein. Eine zu kleine Konfiguration zeigt sich durch häufige Warnungen im Error Log über zu kurze Checkpoint-Intervalle und durch spürbare Performance-Einbrüche bei Schreibspitzen, weil InnoDB gezwungen ist, Flush-Operationen zu erzwingen, statt sie zu bündeln.


# /etc/mysql/conf.d/innodb-redo-log.cnf
[mysqld]
# MySQL 8.0.30+: unified redo log capacity setting
innodb_redo_log_capacity = 4G

# Older MySQL versions: separate file size and count
# innodb_log_file_size = 1G
# innodb_log_files_in_group = 4

innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 1

4. Checkpointing: Fuzzy Checkpoints und Checkpoint Age

Ein Checkpoint markiert den Punkt, bis zu dem alle im Redo Log vermerkten Änderungen tatsächlich in die persistenten Datenseiten übernommen wurden. InnoDB nutzt dabei Fuzzy Checkpointing statt eines vollständigen, blockierenden Checkpoints: Statt alle geänderten Seiten auf einmal zu flushen, was den Betrieb kurzzeitig einfrieren würde, flusht InnoDB kontinuierlich im Hintergrund kleine Batches modifizierter Seiten und verschiebt den Checkpoint dabei schrittweise vorwärts.

Die Differenz zwischen der aktuellen LSN und der Checkpoint-LSN wird als Checkpoint Age bezeichnet und ist eine wichtige Kennzahl für den Gesundheitszustand des Systems. Nähert sich die Checkpoint Age der Kapazitätsgrenze des Redo Log, drosselt InnoDB aktiv neue Schreibzugriffe, um dem Checkpoint-Prozess Zeit zu geben, aufzuholen. Diese Drosselung äußert sich für Anwendungen als spürbarer Latenzanstieg bei Schreiboperationen und ist häufig ein Symptom für ein zu klein dimensioniertes Redo Log in Kombination mit sehr schreiblastigen Workloads.


-- Monitor checkpoint age relative to redo log capacity
SHOW ENGINE INNODB STATUS\G
-- LOG section shows:
-- Log sequence number          145678900000
-- Log flushed up to            145678900000
-- Pages flushed up to          145670000000
-- Last checkpoint at           145660000000
-- Checkpoint age = Log sequence number - Last checkpoint at

-- History list length indicates unpurged undo, correlates with load
SELECT NAME, COUNT
FROM information_schema.INNODB_METRICS
WHERE NAME = 'trx_rseg_history_len';

5. innodb_flush_log_at_trx_commit im Detail

Der Parameter innodb_flush_log_at_trx_commit steuert, wie strikt InnoDB die Durability-Garantie von ACID umsetzt und ist einer der wichtigsten Trade-offs zwischen Sicherheit und Performance im gesamten Redo-Log-System. Bei Wert 1, dem sicheren Standardwert, wird das Redo Log bei jedem Commit sofort geschrieben und mit fsync auf die Platte durchgereicht. Das garantiert, dass keine committete Transaktion bei einem Absturz verloren geht, kostet aber bei jedem einzelnen Commit einen synchronen Festplattenzugriff.

Bei Wert 2 wird das Redo Log bei jedem Commit zwar geschrieben, aber nur einmal pro Sekunde mit fsync tatsächlich persistiert. Ein Absturz des MySQL-Prozesses ist dann unkritisch, weil die Daten im Betriebssystem-Cache liegen, aber ein Absturz des gesamten Servers oder ein Stromausfall kann bis zu eine Sekunde an committeten Transaktionen kosten. Bei Wert 0 wird das Redo Log nur einmal pro Sekunde überhaupt geschrieben, was das höchste Risiko birgt, aber die beste Performance liefert. Für produktive Systeme mit echten Geschäftsdaten ist Wert 1 fast immer die richtige Wahl, Wert 2 kann für Read-Replicas oder unkritische Reporting-Datenbanken eine sinnvolle Kompromisslösung sein.


# /etc/mysql/conf.d/innodb-durability.cnf
[mysqld]
# 1 = safest, fsync on every commit (default, recommended for production)
# 2 = fsync once per second, tolerates mysqld crash but not OS/power loss
# 0 = fsync once per second, highest risk, highest throughput
innodb_flush_log_at_trx_commit = 1

# Benchmark comparison approach:
# SET GLOBAL innodb_flush_log_at_trx_commit = 2;
# Run sysbench write-heavy workload and compare commits/sec vs value 1

6. Der Crash-Recovery-Prozess Schritt für Schritt

Startet der MySQL-Server nach einem unkontrollierten Absturz neu, prüft InnoDB zunächst, ob der letzte Shutdown sauber war. Ist das nicht der Fall, beginnt der automatische Crash-Recovery-Prozess. Im ersten Schritt liest InnoDB das Redo Log ab der letzten Checkpoint-LSN und wendet alle darin verzeichneten Änderungen erneut auf die Datenseiten an, unabhängig davon, ob die zugehörige Transaktion committet wurde oder nicht. Diese Phase heißt Redo-Phase und stellt sicher, dass alle physischen Änderungen wiederhergestellt sind, die vor dem Absturz bereits im Log persistiert waren.

Im zweiten Schritt, der Undo-Phase, identifiziert InnoDB Transaktionen, die zum Absturzzeitpunkt noch nicht committet waren, und rollt sie mithilfe der Undo-Logs zurück. Erst nach Abschluss beider Phasen ist die Datenbank wieder in einem konsistenten Zustand und akzeptiert neue Verbindungen. Bei einem großen Redo Log mit hoher Checkpoint Age kann dieser Prozess mehrere Minuten dauern, was ein wichtiges Argument dafür ist, das Redo Log nicht beliebig groß zu wählen, sondern einen bewussten Kompromiss zwischen Schreibperformance und Recovery-Zeit zu treffen.


# Observe crash recovery progress in the error log
tail -f /var/log/mysql/error.log
# Expected sequence during recovery:
# [Note] InnoDB: Starting crash recovery
# [Note] InnoDB: Restoring buffer pool pages from log
# [Note] InnoDB: Rolling back trx with id 12345, N rows to undo
# [Note] InnoDB: Rollback completed
# [Note] InnoDB: Crash recovery finished

7. Redo Log vs. Undo Log vs. Binlog

Diese drei Log-Typen werden häufig verwechselt, erfüllen aber grundverschiedene Aufgaben. Das Redo Log ist eine InnoDB-interne Struktur und sichert physische Änderungen an Datenseiten für die Crash Recovery ab, wird zirkulär überschrieben und ist für Anwendungen nicht direkt sichtbar. Das Undo Log speichert den vorherigen Zustand geänderter Zeilen, wird für Rollbacks und für MVCC benötigt, damit andere Transaktionen konsistente Lesezugriffe auf ältere Versionen einer Zeile bekommen, und wird nach Abschluss aller relevanten Transaktionen bereinigt.

Das Binary Log, kurz Binlog, ist eine serverweite, logische Aufzeichnung aller datenverändernden Anweisungen und dient primär der Replikation sowie der Point-in-Time-Recovery aus Backups. Anders als das Redo Log wird das Binlog nicht zirkulär überschrieben, sondern rotiert und kann für Wiederherstellungszwecke über längere Zeiträume aufbewahrt werden. Ein häufiger Fehler ist die Annahme, das Redo Log könne das Binlog ersetzen oder umgekehrt, dabei erfüllen beide unterschiedliche, sich ergänzende Zwecke innerhalb derselben Durability-Strategie.

8. Monitoring und typische Probleme

Das wichtigste Monitoring-Signal für das Redo Log ist die bereits erwähnte Checkpoint Age im Verhältnis zur konfigurierten Kapazität. Ein zweites relevantes Signal ist die Anzahl der Redo-Log-Schreibvorgänge pro Sekunde, sichtbar über die Statusvariable Innodb_os_log_written, die bei einer plötzlichen Zunahme auf einen veränderten Workload oder auf ein Problem mit lang laufenden Transaktionen hindeuten kann, die den Checkpoint-Fortschritt blockieren.

Ein klassisches Praxisproblem ist eine einzelne, sehr lange laufende Transaktion, etwa ein vergessener manueller BEGIN ohne COMMIT in einer administrativen Session. Solange diese Transaktion offen bleibt, kann InnoDB die zugehörigen Undo-Informationen nicht bereinigen, was indirekt auch den nutzbaren Spielraum im Redo Log einschränkt und die History List Length wachsen lässt. Ein regelmäßiger Blick auf information_schema.INNODB_TRX deckt solche vergessenen Transaktionen zuverlässig auf.


-- Find long-running transactions that block checkpoint progress
SELECT
    trx_id,
    trx_started,
    TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS seconds_running,
    trx_query
FROM information_schema.INNODB_TRX
ORDER BY trx_started ASC
LIMIT 5;

9. Flush-Strategien im Vergleich

Die Wahl von innodb_flush_log_at_trx_commit ist eine bewusste Entscheidung zwischen Datensicherheit und Durchsatz. Die folgende Tabelle stellt die drei Optionen gegenüber.

Wert Verhalten Risiko bei Absturz Empfehlung
1 fsync bei jedem Commit Kein Datenverlust Produktivsysteme, Standard
2 Schreiben bei Commit, fsync 1x/Sekunde Bis zu 1s bei OS-Crash Read-Replicas, Reporting
0 Schreiben und fsync 1x/Sekunde Bis zu 1s bei jedem Absturz Nur unkritische Testsysteme

Für geschäftskritische Datenbanken mit Bestell- oder Zahlungsdaten ist Wert 1 nicht verhandelbar. Nur bei Systemen, bei denen ein Datenverlust von wenigen Sekunden geschäftlich verkraftbar ist, etwa reine Lese-Replikate für Reporting, kommt Wert 2 als Kompromiss für höheren Durchsatz infrage.

Mironsoft

Datenbank-Resilienz und Recovery-Konzepte

Ist euer Redo Log auf den Ernstfall vorbereitet?

Wir prüfen Redo-Log-Sizing, Checkpoint-Verhalten und Durability-Einstellungen und simulieren Crash-Recovery-Szenarien, damit ein Absturz nicht zur Downtime-Katastrophe wird.

Recovery-Test

Kontrollierte Crash-Recovery-Simulation und Zeitmessung

Log-Sizing

innodb_redo_log_capacity auf euren Workload zugeschnitten

Durability-Audit

flush_log_at_trx_commit je nach Kritikalität der Daten festlegen

10. Zusammenfassung

Das Redo Log ist der Mechanismus, der InnoDB in die Lage versetzt, nach einem Absturz automatisch einen konsistenten Zustand wiederherzustellen, ohne manuelle Reparatur oder Datenverlust bei committeten Transaktionen. Write-Ahead Logging stellt sicher, dass Änderungen persistiert sind, bevor die eigentliche Datenseite geschrieben wird, und Fuzzy Checkpointing hält den Betrieb auch unter Last am Laufen, ohne blockierende Vollflushes.

Die richtige Dimensionierung von innodb_redo_log_capacity beziehungsweise innodb_log_file_size ist ein bewusster Kompromiss zwischen Schreibperformance und Recovery-Zeit. In Kombination mit der richtigen Wahl von innodb_flush_log_at_trx_commit lässt sich das Verhältnis zwischen Datensicherheit und Durchsatz gezielt auf die tatsächliche Kritikalität der Daten abstimmen, statt es dem Zufall zu überlassen.

Redo Log und Crash Recovery, das Wichtigste auf einen Blick

Write-Ahead Logging

Änderungen werden zuerst im Redo Log persistiert, bevor die Datenseite selbst geschrieben wird.

Sizing

1 bis 4 GB für die meisten Systeme, größer für schreiblastige Workloads mit vielen großen Transaktionen.

Durability

innodb_flush_log_at_trx_commit=1 für Produktivsysteme, garantiert keinen Verlust committeter Transaktionen.

Crash Recovery

Läuft beim Start automatisch ab: Redo-Phase gefolgt von Undo-Phase, ohne manuelles Eingreifen.

11. FAQ: Redo Log und Crash Recovery

1Was ist das Redo Log?
Eine InnoDB-interne Struktur, die physische Änderungen via Write-Ahead Logging persistiert, bevor die Datenseite selbst geschrieben wird.
2Wie groß sollte es sein?
1 bis 4 GB für die meisten Systeme, größer bei sehr schreiblastigen Workloads mit vielen großen Transaktionen.
3Was ist Checkpoint Age?
Differenz zwischen aktueller LSN und Checkpoint-LSN. Nahe der Kapazitätsgrenze drosselt InnoDB neue Schreibzugriffe.
4Was bedeutet Wert 1?
Redo Log wird bei jedem Commit sofort mit fsync geschrieben. Garantiert keinen Verlust committeter Transaktionen.
5Wie lange dauert Recovery?
Von Sekunden bis zu mehreren Minuten, abhängig von Checkpoint Age und Redo-Log-Größe zum Absturzzeitpunkt.
6Redo Log vs. Undo Log?
Redo Log sichert Crash Recovery ab. Undo Log speichert vorherige Zeilenzustände für Rollbacks und MVCC.
7Ersetzt Binlog das Redo Log?
Nein. Binlog dient Replikation und Point-in-Time-Recovery, Redo Log der InnoDB-internen Crash Recovery. Beide ergänzen sich.
8Was ist Fuzzy Checkpointing?
Kontinuierliches Flushen kleiner Batches im Hintergrund statt eines blockierenden Vollflushes aller geänderten Seiten.
9Wann Wert 2 sinnvoll?
Für Read-Replicas oder unkritische Reporting-Systeme, wo ein Verlust von bis zu einer Sekunde bei OS-Crash akzeptabel ist.
10Redo Log zu klein?
Häufigere erzwungene Checkpoints und Drosselung von Schreibzugriffen, sichtbar als Latenzanstieg bei Schreibspitzen.