MySQL Binlog-Formate: Statement, Row, Mixed
AI generated
InnoDB
SQL
MySQL · Binlog · Replikation · binlog_format
Binlog-Formate im Vergleich
Statement, Row und Mixed

Das Binlog-Format entscheidet darüber, ob MySQL-Replikation bei nicht-deterministischen Statements zuverlässig bleibt oder still auseinanderdriftet. STATEMENT, ROW und MIXED unterscheiden sich fundamental in Größe, Sicherheit und Nachvollziehbarkeit, und die Wahl des richtigen Formats ist eine der folgenreichsten Konfigurationsentscheidungen in jeder MySQL-Installation.

18 Min. Lesezeit binlog_format · mysqlbinlog · Replikationssicherheit MySQL 8.0 · InnoDB · Row-Based Replication

1. Was das Binlog überhaupt protokolliert

Das Binary Log, kurz Binlog, ist das zentrale Änderungsprotokoll von MySQL und die Grundlage jeder Form von Replikation sowie Point-in-Time-Recovery aus Backups. Jede Datenänderung, die auf einer Instanz mit aktiviertem log_bin ausgeführt wird, landet im Binlog, bevor sie als abgeschlossen gilt. Das Binlog-Format bestimmt dabei, in welcher Granularität diese Änderungen aufgezeichnet werden, und diese Entscheidung hat weitreichende Konsequenzen für Replikationssicherheit, Speicherbedarf und Debugging-Fähigkeit.

MySQL bietet drei mögliche Werte für binlog_format: STATEMENT protokolliert die ausgeführte SQL-Anweisung selbst, ROW protokolliert die tatsächlichen Änderungen an einzelnen Zeilen, und MIXED wechselt situationsabhängig zwischen beiden Modi. Die Wahl des Binlog-Formats war über Jahre eine der am meisten unterschätzten Konfigurationsentscheidungen in MySQL-Betrieb, weil STATEMENT lange der Standard war, obwohl es bekannte Sicherheitslücken bei der Replikation hat.

2. STATEMENT-Format: SQL-Anweisungen als Log

Im STATEMENT-basierten Binlog-Format schreibt MySQL die tatsächlich ausgeführte SQL-Anweisung ins Binlog, etwa UPDATE products SET price = price * 1.1 WHERE category_id = 5. Auf der Replica wird exakt dieselbe Anweisung erneut ausgeführt. Der große Vorteil dieses Ansatzes liegt in der kompakten Größe: Eine einzelne SQL-Anweisung, die tausend Zeilen betrifft, erzeugt nur einen einzigen kurzen Log-Eintrag, unabhängig davon, wie viele Zeilen tatsächlich verändert wurden.

Genau diese Kompaktheit ist jedoch auch die Schwäche des STATEMENT-Formats: Es funktioniert nur korrekt, wenn die Anweisung auf der Replica exakt dasselbe Ergebnis produziert wie auf der Quelle. Funktionen wie NOW(), RAND(), UUID() oder Anweisungen, die von der Ausführungsreihenfolge oder dem internen Zustand abhängen, wie LIMIT ohne ORDER BY bei UPDATE-Statements, können auf der Quelle und der Replica unterschiedliche Ergebnisse liefern. Das Binlog-Format STATEMENT verlässt sich darauf, dass solche Nicht-Determinismen entweder vermieden oder von MySQL automatisch in eine sichere, deterministische Form übersetzt werden, was nicht immer zuverlässig gelingt.


-- Enable STATEMENT format explicitly (not recommended for production)
SET GLOBAL binlog_format = 'STATEMENT';

-- This statement replicates safely under STATEMENT format
UPDATE products SET price = price * 1.1 WHERE category_id = 5;

-- This statement is unsafe under STATEMENT format and only issues a warning
UPDATE products SET last_price_change = NOW() WHERE category_id = 5;
-- Warning (1592): Statement may not be safe to log in statement format.

-- mysqlbinlog on a STATEMENT-format log shows the original SQL directly
-- #260723 10:15:03 server id 1  end_log_pos 512
-- UPDATE products SET price = price * 1.1 WHERE category_id = 5

3. ROW-Format: Zeilenänderungen statt SQL

Im ROW-basierten Binlog-Format protokolliert MySQL nicht die SQL-Anweisung, sondern die tatsächlichen Vorher- und Nachher-Werte jeder betroffenen Zeile. Ein UPDATE, das tausend Zeilen ändert, erzeugt tausend einzelne Row-Events, jedes mit den exakten Spaltenwerten vor und nach der Änderung. Dieses Vorgehen eliminiert das Nicht-Determinismus-Problem vollständig: Die Replica wendet exakt dieselben Zeilenänderungen an, unabhängig davon, welche Funktion oder welche Ausführungsreihenfolge auf der Quelle zum Ergebnis geführt hat.

Der Preis für diese Sicherheit ist ein deutlich größeres Binlog-Volumen bei Anweisungen, die viele Zeilen betreffen, weil jede Zeile einzeln protokolliert wird statt der kompakten SQL-Anweisung. Für Massen-Updates mit Millionen betroffener Zeilen kann das ROW-Format das Binlog-Volumen um ein Vielfaches gegenüber STATEMENT erhöhen. Trotzdem ist ROW seit MySQL 5.7 der empfohlene Standard und in MySQL 8.0 sogar der Default-Wert für binlog_format, weil die Garantie korrekter Replikation in der Praxis fast immer schwerer wiegt als der zusätzliche Speicherbedarf.


# my.cnf: enabling ROW-based binary logging with a full row image
[mysqld]
server-id = 1
log_bin = /var/log/mysql/binlog
binlog_format = ROW
binlog_row_image = FULL
gtid_mode = ON
enforce_gtid_consistency = ON

# Optional: compress binlog events to offset the larger ROW format size
binlog_transaction_compression = ON

4. MIXED-Format: automatischer Wechsel zwischen beiden

Das MIXED Binlog-Format versucht, die Vorteile beider Welten zu kombinieren: Standardmäßig verwendet MySQL STATEMENT-basierte Protokollierung für Anweisungen, die als sicher deterministisch gelten, und wechselt automatisch zu ROW-basierter Protokollierung, sobald der Server ein Statement erkennt, das potenziell nicht-deterministisches Verhalten aufweisen könnte, etwa den Aufruf von UUID() oder eine gespeicherte Prozedur mit unsicherem Inhalt.

In der Praxis erweist sich MIXED als Kompromiss, der selten wirklich überzeugt: Die Größenvorteile von STATEMENT gehen für viele alltägliche Anweisungen verloren, weil moderne Anwendungen ständig Funktionen wie NOW() für Zeitstempel verwenden, was MySQL regelmäßig zum Wechsel in den ROW-Modus zwingt. Gleichzeitig bleibt die Komplexität bestehen, zwei unterschiedliche Protokollierungsmodi im selben Binlog zu haben, was Debugging und die Analyse mit mysqlbinlog erschwert, weil Werkzeuge und Administratoren beide Formate gleichzeitig verstehen müssen.

5. Nicht-deterministische Statements als Kernproblem

Der eigentliche Grund, warum das Binlog-Format überhaupt zur kritischen Konfigurationsentscheidung wird, liegt in nicht-deterministischen SQL-Konstrukten. Ein UPDATE mit LIMIT 100 ohne ORDER BY kann bei jeder Ausführung eine andere Teilmenge von Zeilen betreffen, weil die interne Speicherreihenfolge der Zeilen zwischen Quelle und Replica variieren kann, insbesondere nach unterschiedlichen Wartungsoperationen wie OPTIMIZE TABLE. Bei STATEMENT-Format würde eine solche Anweisung auf der Replica erneut ausgeführt und könnte dort andere Zeilen treffen als auf der Quelle, ein subtiler und schwer zu findender Bug.

Auch Trigger und gespeicherte Prozeduren mit interner Logik, die von Sitzungsvariablen oder Zeitpunkten abhängt, sind klassische Kandidaten für Nicht-Determinismus. MySQL markiert solche Konstrukte intern als UNSAFE und schreibt bei MIXED-Format automatisch einen ROW-Event anstelle des Statements. Bei explizit auf STATEMENT gesetztem Binlog-Format gibt der Server lediglich eine Warnung aus, verhindert die potenziell inkorrekte Replikation aber nicht, was STATEMENT für produktive Systeme mit komplexer Anwendungslogik zu einem vermeidbaren Risiko macht.


-- Example of a non-deterministic UPDATE that is unsafe under STATEMENT format
UPDATE products
SET featured = 1
LIMIT 100;  -- no ORDER BY: row order is not guaranteed to match between servers

-- MIXED format automatically falls back to ROW logging for this statement
-- STATEMENT format would replay it as-is and can hit a different set of rows

-- Check whether the server flagged a statement as unsafe
SHOW WARNINGS;
-- Level | Code | Message
-- Note  | 1592 | Statement may not be safe to log in statement format.

6. Binlog-Größe: Row vs. Statement in der Praxis

Die Größendifferenz zwischen ROW- und STATEMENT-Binlog hängt stark vom Workload-Muster ab. Bei Anwendungen mit vielen kleinen, gezielten Einzeiländerungen, etwa dem klassischen Web-Anwendungsmuster mit einzelnen INSERT- und UPDATE-Statements pro Request, ist der Größenunterschied zwischen den Formaten gering, weil ohnehin nur wenige Zeilen pro Anweisung betroffen sind. Bei Batch-Jobs, Massen-Imports oder großen UPDATE-Anweisungen, die tausende oder Millionen Zeilen gleichzeitig ändern, kann ROW-Format das Binlog-Volumen dramatisch erhöhen.

Für solche Fälle bietet MySQL binlog_row_image als Stellschraube: Der Standardwert FULL protokolliert alle Spalten vor und nach der Änderung, MINIMAL protokolliert nur die tatsächlich geänderten Spalten sowie die zur eindeutigen Identifikation der Zeile nötigen Spalten. Für Tabellen mit vielen Spalten, von denen bei einem typischen UPDATE nur wenige geändert werden, reduziert MINIMAL das Binlog-Volumen erheblich, ohne die Vorteile der ROW-basierten Replikationssicherheit aufzugeben. Zusätzlich komprimiert binlog_transaction_compression seit MySQL 8.0.20 Binlog-Events auf Transaktionsebene und reduziert den Speicherbedarf zusätzlich, besonders bei sich wiederholenden Datenmustern.

7. Format konfigurieren und Row-Image-Optionen tunen

Die Umstellung des Binlog-Formats erfolgt über die Serverkonfiguration und kann sowohl global als auch pro Session gesetzt werden, was für gezielte Migrationen oder Ausnahmefälle nützlich ist. Ein globaler Wechsel erfordert typischerweise keinen Neustart des Servers, da binlog_format eine dynamische Variable ist, sollte aber sorgfältig geplant werden, weil bereits laufende Transaktionen konsistent im bisherigen Format abgeschlossen werden müssen.


-- Check the current binlog format
SHOW VARIABLES LIKE 'binlog_format';
SHOW VARIABLES LIKE 'binlog_row_image';

-- Change globally at runtime (new connections pick up the change)
SET GLOBAL binlog_format = 'ROW';
SET GLOBAL binlog_row_image = 'MINIMAL';

-- Change for the current session only, useful for testing before a full rollout
SET SESSION binlog_format = 'ROW';

-- Persist the change in configuration for the next restart
-- [mysqld]
-- binlog_format = ROW
-- binlog_row_image = MINIMAL
-- binlog_row_metadata = FULL

Bei einem Wechsel von STATEMENT oder MIXED auf ROW ist es wichtig, alle Replicas gleichzeitig oder mit minimaler zeitlicher Verzögerung umzustellen, um Kompatibilitätsprobleme während der Übergangsphase zu vermeiden. In gemischten Umgebungen, in denen einige Replicas noch ältere MySQL-Versionen ausführen, sollte vorab geprüft werden, ob alle Versionen das gewünschte Binlog-Format und die zugehörigen Row-Image-Optionen vollständig unterstützen.

8. Binlogs analysieren mit mysqlbinlog

Das Kommandozeilenwerkzeug mysqlbinlog dekodiert Binlog-Dateien in lesbare oder erneut ausführbare SQL-Form, unabhängig vom verwendeten Binlog-Format. Bei STATEMENT-Format zeigt die Ausgabe direkt die ursprünglichen SQL-Anweisungen, bei ROW-Format werden die binär kodierten Zeilenänderungen mit der Option --verbose in eine pseudo-SQL-Darstellung übersetzt, die zwar lesbar, aber nicht identisch mit der ursprünglichen Anweisung ist.


# Decode a ROW-format binlog into human-readable pseudo-SQL
mysqlbinlog --verbose --base64-output=decode-rows /var/log/mysql/binlog.000042

# Extract only events for a specific database and time window
mysqlbinlog --database=shop \
  --start-datetime="2026-07-23 08:00:00" \
  --stop-datetime="2026-07-23 09:00:00" \
  /var/log/mysql/binlog.000042 | less

# Replay a binlog to recover data up to a specific point in time
mysqlbinlog --stop-position=154892 /var/log/mysql/binlog.000042 | mysql -u root -p

Diese Analysefähigkeit ist besonders wertvoll bei Point-in-Time-Recovery nach einem versehentlichen DELETE ohne WHERE-Klausel: Aus dem Binlog lässt sich der exakte Zeitpunkt oder die exakte Binlog-Position vor dem fehlerhaften Statement extrahieren, und die Wiederherstellung kann bis genau zu diesem Punkt erfolgen. Bei ROW-Format ist diese Wiederherstellung präziser, weil jede einzelne Zeilenänderung nachvollziehbar ist, während bei STATEMENT-Format nur die ursprüngliche Anweisung sichtbar ist, ohne Information darüber, welche konkreten Zeilen sie tatsächlich betroffen hat.

9. Statement vs. Row vs. Mixed im Vergleich

Die Wahl des richtigen Binlog-Formats hängt von der Priorität zwischen Speicherplatz, Replikationssicherheit und Debugging-Komfort ab. Die folgende Tabelle fasst die wichtigsten Unterschiede zusammen.

Kriterium STATEMENT ROW MIXED
Replikationssicherheit Risiko bei nicht-deterministischen Statements Vollständig sicher, keine Ambiguität Meist sicher, abhängig von Erkennung
Binlog-Größe bei Batch-Writes Kompakt, unabhängig von Zeilenzahl Kann deutlich größer werden Variabel je nach Statement-Typ
Debugging-Komfort Direkt lesbar als SQL Lesbar nur mit mysqlbinlog --verbose Gemischt, zwei Formate im selben Log
Parallelisierbarkeit auf Replica Eingeschränkt Granularer, bessere MTS-Unterstützung Abhängig vom gewählten Modus je Statement
Empfehlung Nur für sehr einfache, geprüfte Workloads Standard in MySQL 8.0, empfohlen Übergangslösung, selten die beste Wahl

In der Praxis ist ROW-Binlog-Format für die überwiegende Mehrheit der produktiven MySQL-Installationen die richtige Wahl, weil die Garantie korrekter Replikation die zusätzlichen Speicherkosten fast immer rechtfertigt, insbesondere in Kombination mit binlog_row_image = MINIMAL und Transaktionskompression zur Größenreduktion.

Mironsoft

MySQL Binlog-Konfiguration, Replikationssicherheit und Backup-Strategie

Binlog-Format, das Replikation nicht heimlich sabotiert?

Wir prüfen euer aktuelles Binlog-Format auf Replikationsrisiken, migrieren sicher auf ROW-Format und optimieren Binlog-Größe über Row-Image- und Kompressionseinstellungen.

Binlog-Audit

Analyse auf nicht-deterministische Statements und Replikationsrisiken

Format-Migration

Sicherer Wechsel auf ROW-Format ohne Replikationsausfall

Größen-Optimierung

Row-Image und Transaktionskompression für schlankere Binlogs

10. Zusammenfassung

Das Binlog-Format ist keine Nebensächlichkeit, sondern eine Konfigurationsentscheidung mit direkten Auswirkungen auf Datenintegrität in der Replikation. STATEMENT bietet kompakte Logs, birgt aber echtes Risiko bei nicht-deterministischen Anweisungen. ROW eliminiert dieses Risiko vollständig, kostet dafür mehr Speicherplatz bei Massen-Operationen. MIXED verspricht einen Kompromiss, liefert aber selten die erhoffte Balance und erschwert Debugging durch zwei parallele Formate im selben Log.

Für praktisch jede produktive MySQL-Installation ist ROW-Binlog-Format die richtige Standardwahl, ergänzt um binlog_row_image = MINIMAL und Transaktionskompression zur Kontrolle des Speicherbedarfs. Wer das Binlog zusätzlich für Point-in-Time-Recovery nutzt, profitiert bei ROW-Format von präziserer Nachvollziehbarkeit einzelner Zeilenänderungen, ein Vorteil, der bei STATEMENT-Format schlicht nicht existiert.

MySQL Binlog-Formate: Das Wichtigste auf einen Blick

STATEMENT

Kompakte SQL-Logs, aber Risiko bei NOW(), RAND(), UUID() und LIMIT ohne ORDER BY.

ROW

Protokolliert echte Zeilenänderungen, vollständig sicher, Standard seit MySQL 8.0.

MIXED

Automatischer Wechsel je nach Statement, in der Praxis selten die beste Wahl.

Größenkontrolle

binlog_row_image = MINIMAL und binlog_transaction_compression reduzieren Volumen.

11. FAQ: MySQL Binlog-Formate

1Welches Format ist aktueller Standard?
ROW ist seit MySQL 8.0 der Default und die von Oracle empfohlene Einstellung.
2Warum ist STATEMENT riskant?
Nicht-deterministische Funktionen wie NOW() oder RAND() können auf Quelle und Replica abweichende Ergebnisse liefern.
3Wie viel größer ist ROW gegenüber STATEMENT?
Hängt vom Workload ab, bei Massen-Updates kann der Unterschied erheblich sein, bei Einzeiländerungen gering.
4MINIMAL vs. FULL Row-Image?
MINIMAL protokolliert nur geänderte plus Identifikationsspalten, reduziert Binlog-Größe erheblich.
5Ist MIXED gut für neue Setups?
Selten, da MIXED bei vielen Alltagsanweisungen ohnehin zu ROW wechselt, aber die Debugging-Komplexität bestehen bleibt.
6Format ohne Neustart ändern?
Ja, mit SET GLOBAL binlog_format = 'ROW' zur Laufzeit, wirkt auf neue Verbindungen und Transaktionen.
7Wie lese ich ROW-Binlogs?
mysqlbinlog --verbose --base64-output=decode-rows übersetzt binäre Row-Events in lesbare Pseudo-SQL.
8Beeinflusst Format MTS-Parallelisierung?
Ja, ROW ermöglicht granularere Parallelisierung, weil Zeilenänderungen unabhängiger sind als SQL-Anweisungen.
9Format bei Point-in-Time-Recovery?
ROW ermöglicht präzisere Wiederherstellung, da jede Zeilenänderung einzeln nachvollziehbar ist.
10Lohnt sich Transaktionskompression?
Bei größerem ROW-Binlog-Volumen meist ja, kostet aber etwas CPU-Zeit für Komprimierung und Dekomprimierung.