GTID-basierte Replikation praktisch einsetzen
AI generated
InnoDB
SQL
MySQL · Replikation · GTID
GTID-basierte Replikation
praktisch einsetzen statt Positions-Koordinaten zu pflegen

Global Transaction Identifiers lösen ein Problem, das jeder kennt, der nach einem Crash manuell die richtige Binlog-Position für CHANGE MASTER TO gesucht hat. Wer eine bestehende, positionsbasierte Replikation ohne Datenverlust auf GTIDs umstellt, gewinnt automatisches Failover-Handling und verliert eine ganze Klasse von Betriebsfehlern gleichzeitig.

12 Min. Lesezeit Hochverfügbarkeit Praxis-Migration

1. Was GTIDs sind und wie sie sich von Binlog-Positionen unterscheiden

Klassische MySQL-Replikation identifiziert jede Transaktion über ein Koordinatenpaar aus Binlog-Dateiname und Byte-Position, etwa mysql-bin.000042 an Position 1874392. Diese Koordinaten sind serverspezifisch: Ein Replica kennt seine eigene Position im Relay-Log, aber nicht automatisch, welcher Punkt im Binlog des Sources dazu passt, wenn nach einem Failover ein neuer Source übernehmen soll. Genau diese Übersetzungsarbeit musste bislang von Hand geleistet werden, meist unter Zeitdruck und mit Fehlerrisiko.

Eine Global Transaction Identifier besteht aus der Server-UUID des Ursprungsservers und einer fortlaufenden Transaktionsnummer, zum Beispiel 3E11FA47-71CA-11E1-9E33-C80AA9429562:23. Diese ID ist global eindeutig und bleibt über die gesamte Topologie hinweg gültig, unabhängig davon, über wie viele Zwischenknoten eine Transaktion repliziert wurde. Jeder Server kennt damit nicht nur seine eigene Position, sondern die exakte Identität jeder einzelnen Transaktion, die er je verarbeitet hat.

2. Automatisches Failover-Handling durch GTIDs

Bei positionsbasierter Replikation musste nach einem Failover jemand manuell ermitteln, an welcher Binlog-Position des neuen Sources ein Replica ansetzen soll, oft durch mühsamen Vergleich von Zeitstempeln und Statement-Inhalten in mehreren Binlog-Dateien. Ein einziger Fehler bei dieser Zuordnung führt entweder zu doppelt angewendeten Transaktionen oder zu stillschweigend übersprungenen Daten, beides schwer zu erkennende Fehlerbilder.

Mit GTIDs entfällt diese manuelle Übersetzung vollständig. Ein Replica meldet dem neuen Source einfach seine vollständige gtid_executed-Menge, der Source berechnet die Differenz zur eigenen Menge und streamt ausschließlich die fehlenden Transaktionen. Dieser Mechanismus ist die Grundlage, auf der moderne HA-Werkzeuge wie MySQL Router, Orchestrator oder InnoDB Cluster überhaupt erst zuverlässiges automatisches Failover anbieten können, ohne menschliches Eingreifen bei der Positionsermittlung.

3. gtid_mode aktivieren: Voraussetzungen und Server-Variablen

GTID-Replikation setzt log_bin, eine eindeutige server_id sowie enforce_gtid_consistency voraus. Letzteres verbietet Anweisungen, die sich nicht sauber als einzelne GTID abbilden lassen, etwa gemischte Updates über transaktionale und nicht-transaktionale Engines in einer Transaktion, CREATE TABLE ... SELECT sowie temporäre Tabellen innerhalb replizierter Transaktionen. Vor der eigentlichen Umstellung lohnt sich ein Testlauf mit dem WARN-Modus, um inkompatible Statements im laufenden Betrieb aufzuspüren, ohne sie sofort zu blockieren.

Erst wenn der WARN-Modus über einen repräsentativen Zeitraum keine Verstöße mehr meldet, sollte auf den strengen ON-Modus umgestellt werden. Diese Reihenfolge verhindert, dass die spätere GTID-Aktivierung von Anwendungscode ausgebremst wird, der bislang unbemerkt inkompatible Muster verwendet hat, etwa Legacy-Skripte, die Report-Tabellen als temporäre Tabelle innerhalb einer replizierten Transaktion anlegen.


-- Schritt 1: Inkompatible Statements im Betrieb aufspüren, ohne zu blockieren
SET PERSIST enforce_gtid_consistency = WARN;

-- Nach ausreichender Beobachtungszeit ohne Warnungen im error log:
SET PERSIST enforce_gtid_consistency = ON;

-- Aktuellen Modus pruefen
SELECT @@GLOBAL.enforce_gtid_consistency, @@GLOBAL.gtid_mode;

4. Migration von positionsbasierter zu GTID-Replikation ohne Datenverlust

MySQL bietet für genau diesen Fall einen offiziellen, vierstufigen Übergang: OFF, OFF_PERMISSIVE, ON_PERMISSIVE, ON. In den beiden Permissive-Stufen akzeptiert der Server sowohl Transaktionen mit als auch ohne GTID gleichzeitig, sodass Source und Replicas nacheinander umgestellt werden können, ohne dass die Replikation zwischendurch abreißt. Die Reihenfolge ist dabei bindend: Zunächst wechseln alle Replicas auf OFF_PERMISSIVE, danach der Source, anschließend alle Replicas auf ON_PERMISSIVE, danach wieder der Source, erst zum Schluss folgt der finale Schritt auf ON überall.

Zwischen den Stufen muss jeweils abgewartet werden, bis keine anonymen, also nicht-GTID-basierten, Transaktionen mehr im System zirkulieren. Der Status lässt sich über die Variable ongoing_anonymous_transaction_count prüfen, die erst auf null zurückgehen muss, bevor der nächste Schritt sicher ist. Wer diesen Zwischenschritt überspringt, riskiert, dass einzelne Transaktionen ohne GTID im permissiven Fenster verlorengehen, sobald der strenge Modus greift.


# Auf jedem Replica, dann auf dem Source, jeweils in dieser Reihenfolge ausführen
mysql -e "SET PERSIST gtid_mode = OFF_PERMISSIVE;"
# ... warten bis ongoing_anonymous_transaction_count = 0 auf allen Knoten
mysql -e "SET PERSIST gtid_mode = ON_PERMISSIVE;"
# ... erneut warten, dann pro Knoten:
mysql -e "SET PERSIST gtid_mode = ON;"
mysql -e "SELECT @@GLOBAL.gtid_mode, @@GLOBAL.ongoing_anonymous_transaction_count;"

5. GTID-Sets lesen und verstehen: gtid_executed und gtid_purged

Die Variable gtid_executed enthält alle Transaktionen, die ein Server jemals committet hat, als kompakte Menge von UUID-Bereichen, etwa 3E11FA47-...9562:1-874. gtid_purged ist die Teilmenge davon, deren Binlog-Einträge bereits durch Rotation oder PURGE BINARY LOGS physisch gelöscht wurden, aber weiterhin als bekannt geführt werden müssen, damit ein neuer Replica beim Auto-Position-Abgleich nicht versucht, längst gelöschte Transaktionen anzufordern.

Für gezieltes Extrahieren einzelner Transaktionsbereiche aus einem Binlog-Archiv eignet sich mysqlbinlog mit der Option --include-gtids, etwa um nach einem fehlerhaften Deployment nur die Statements einer bestimmten Anwendung erneut anzuwenden. Diese gezielte Extraktion ist mit reinen Positionsangaben praktisch nicht möglich, weil Positionen keine inhaltliche Zuordnung zu einer logischen Transaktionsquelle erlauben.


SELECT @@GLOBAL.gtid_executed;
SELECT @@GLOBAL.gtid_purged;

-- Gezielte Extraktion aus dem Binlog-Archiv per mysqlbinlog:
-- mysqlbinlog --include-gtids='3E11FA47-71CA-11E1-9E33-C80AA9429562:500-874' \
--   mysql-bin.000042 | mysql -u root -p

6. Externally defined GTIDs und Errant Transactions erkennen

Eine Errant Transaction entsteht, wenn direkt auf einem Replica geschrieben wird und dabei eine eigene GTID erzeugt wird, die niemals vom Source stammt. Solange dieses Replica nur lesend dient, bleibt der Effekt oft unbemerkt. Kritisch wird es erst, wenn genau dieses Replica später zum neuen Source befördert wird: Es bringt dann eine GTID mit, die kein anderer Knoten kennt, und die Topologie divergiert, oft erst Tage später sichtbar durch inkonsistente Daten.

Die zuverlässigste Prävention ist eine konsequente read_only- und super_read_only-Konfiguration auf allen Replicas, sodass nur der Replikations-Thread selbst schreiben kann. Zur Erkennung bestehender Errant Transactions eignet sich ein Vergleich der GTID-Sets zwischen allen Knoten mittels GTID_SUBTRACT: Jede GTID, die auf einem Replica auftaucht, aber nicht im Set des aktuellen Sources enthalten ist, ist ein Kandidat für eine Errant Transaction und sollte vor jedem geplanten Failover geprüft werden.


-- Auf dem Replica ausgefuehrt, source_gtid_executed vorher vom Source kopiert:
SELECT GTID_SUBTRACT(@@GLOBAL.gtid_executed, 'source_gtid_executed_hier_einsetzen')
  AS moegliche_errant_transactions;

7. CHANGE REPLICATION SOURCE TO mit SOURCE_AUTO_POSITION in der Praxis

Sobald GTIDs überall aktiv sind, reduziert sich die Replica-Konfiguration auf Host, Zugangsdaten und die Option SOURCE_AUTO_POSITION=1, ganz ohne Angabe von Logdatei oder Position. Der Server übernimmt den vollständigen Abgleich selbstständig und meldet einen klaren Fehler, wenn eine Errant Transaction den automatischen Abgleich verhindert, statt wie früher stillschweigend an der falschen Stelle weiterzumachen.

Dieses Verhalten macht Runbooks für Failover deutlich kürzer und weniger fehleranfällig: Statt einer mehrstufigen Anleitung zum Vergleich von Binlog-Dateien genügt ein einziger, immer gleicher Befehl pro Replica, unabhängig davon, welcher Knoten gerade als Source fungiert.


CHANGE REPLICATION SOURCE TO
  SOURCE_HOST = 'db-primary-neu.internal',
  SOURCE_USER = 'repl',
  SOURCE_PASSWORD = 'geheim',
  SOURCE_AUTO_POSITION = 1;

START REPLICA;
SHOW REPLICA STATUS\G

8. Monitoring: SHOW REPLICA STATUS und die Performance-Schema-Sicht auf GTIDs

SHOW REPLICA STATUS liefert mit Retrieved_Gtid_Set und Executed_Gtid_Set zwei zentrale Felder: Ersteres zeigt, was bereits im Relay-Log angekommen ist, letzteres, was tatsächlich angewendet wurde. Die Differenz zwischen beiden Mengen entspricht exakt dem noch nicht verarbeiteten Rückstand, unabhängig von der oft ungenauen Sekunden-Schätzung in Seconds_Behind_Source.

Für eine belastbare Rückstands-Zahl empfiehlt sich eine Abfrage mit GTID_SUBTRACT zwischen den beiden Mengen, die im Gegensatz zur reinen Zeitschätzung die tatsächliche Anzahl offener Transaktionen liefert. Diese Zahl lässt sich in ein Monitoring-Dashboard integrieren und ist besonders bei Multi-Threaded-Replication präziser als jede zeitbasierte Näherung, weil sie transaktionsgenau statt geschätzt ist.


SELECT GTID_SUBTRACT(Retrieved_Gtid_Set, Executed_Gtid_Set) AS noch_offen
FROM performance_schema.replication_connection_status
JOIN performance_schema.replication_applier_status
  USING (channel_name);

9. Fallstricke im GTID-Betrieb: Multi-Source, Backups und Restores

Bei Multi-Source-Replikation, bei der ein Server Transaktionen von mehreren unabhängigen Quellen empfängt, muss die Eindeutigkeit der Server-UUID über alle Kanäle hinweg gewährleistet bleiben, sonst kollidieren GTID-Bereiche und einzelne Transaktionen werden fälschlicherweise als bereits angewendet übersprungen. Klonte Instanzen mit identischer UUID sind hier eine häufige, aber vermeidbare Fehlerquelle, insbesondere nach dem Hochfahren aus einem Snapshot ohne vorheriges RESET MASTER und neue UUID-Generierung.

Nach einem Restore aus einem Backup muss gtid_purged auf dem Zielserver explizit gesetzt werden, damit spätere Auto-Position-Anfragen wissen, welche Transaktionen bereits im Backup enthalten waren, aber nicht mehr im Binlog vorliegen. Sowohl mysqldump --single-transaction --set-gtid-purged=ON als auch Percona XtraBackup schreiben diese Information automatisch in ihre Ausgabe, wird sie beim Restore ignoriert, bricht die spätere Replikation mit einer schwer diagnostizierbaren Fehlermeldung ab.

Aspekt Positionsbasiert GTID-basiert Praxis-Konsequenz
Failover-Wiederanschluss Manuelles Ermitteln von Log-Datei und Position Automatischer Abgleich über gtid_executed Deutlich kürzere Wiederherstellungszeit
Fehleranfälligkeit Hoch bei manuellen CHANGE MASTER TO Befehlen Gering, Server berechnet Position selbst Weniger menschliche Fehler im Ernstfall
Kompatibilität Funktioniert mit gemischten Storage-Engines Erfordert transaktionale Konsistenz Vor Umstellung Statement-Kompatibilität mit WARN prüfen
Multi-Source-Setups Positionen pro Kanal getrennt verwaltbar Globale Eindeutigkeit über Server-UUID nötig Server-UUID-Kollisionen aktiv vermeiden
Werkzeug-Unterstützung Ältere Skripte teils inkompatibel Native Unterstützung in Router, InnoDB Cluster Moderne HA-Tools setzen GTID praktisch voraus
Migrationsaufwand Kein Aufwand, Ausgangszustand Vierstufiger Übergang ohne Downtime möglich Umstellung ist planbar, aber mehrstufig

Mironsoft

Datenbank-Performance, Index-Tuning und Magento-DB-Optimierung

Magento-Shop, der an langsamen Datenbankabfragen leidet?

Wir analysieren MySQL-Datenbanken auf Performance-Bremsen, optimieren Indizes und Abfragen gezielt und richten Backup- und Replikationsstrategien ein, die im Ernstfall wirklich funktionieren.

Performance-Audit

Slow Query Log und Explain-Pläne systematisch auf Engpässe untersuchen.

Index-Optimierung

Indizes gezielt für die tatsächliche Abfragelast des Shops aufbauen.

Backup-Strategie

Zuverlässige Backup- und Restore-Prozesse für produktive Magento-Datenbanken einrichten.

10. Zusammenfassung

GTID-Replikation: Das Wichtigste auf einen Blick

Kernidee

Jede Transaktion erhält eine global eindeutige ID aus Server-UUID und laufender Nummer, statt über Datei und Byte-Position identifiziert zu werden.

Migration

Der offizielle vierstufige Übergang OFF, OFF_PERMISSIVE, ON_PERMISSIVE, ON erlaubt die Umstellung im laufenden Betrieb ohne Datenverlust.

Größter Nutzen

SOURCE_AUTO_POSITION=1 übernimmt den Abgleich fehlender Transaktionen automatisch, das manuelle Suchen der Log-Position entfällt vollständig.

Größte Gefahr

Errant Transactions, direkt auf einem Replica erzeugt, brechen die Topologie und müssen über konsequente Read-Only-Konfiguration verhindert werden.

11. FAQ: GTID-Replikation: Das Wichtigste auf einen Blick

1Was ist eine GTID genau?
Eine Global Transaction Identifier besteht aus der UUID des Servers, auf dem eine Transaktion ursprünglich committet wurde, und einer fortlaufenden Nummer innerhalb dieses Servers, etwa 3E11FA47-71CA-11E1-9E33-C80AA9429562:23. Sie ist über die gesamte Replikationstopologie hinweg eindeutig und identifiziert eine Transaktion unabhängig davon, über wie viele Zwischenserver sie gelaufen ist.
2Kann ich gtid_mode ohne Ausfallzeit aktivieren?
Ja, über den offiziellen vierstufigen Übergang OFF, OFF_PERMISSIVE, ON_PERMISSIVE, ON. In den Permissive-Stufen akzeptiert der Server gleichzeitig Transaktionen mit und ohne GTID, sodass Source und Replicas nacheinander umgestellt werden können, ohne dass die Replikation zwischendurch unterbrochen werden muss.
3Was passiert bei einer Errant Transaction?
Eine Errant Transaction entsteht, wenn direkt auf einem Replica geschrieben wird und dabei eine GTID erzeugt wird, die niemals vom Source stammt. Wird dieses Replica später zum Source befördert, divergiert die Topologie, weil andere Knoten diese GTID nicht kennen und die automatische Positionsermittlung fehlschlägt.
4Wie verhindere ich Errant Transactions zuverlässig?
Am zuverlässigsten über eine konsequente read_only- und super_read_only-Konfiguration auf allen Replicas, sodass nur der Replikations-Thread selbst schreiben darf. Manuelle Wartungsarbeiten auf einem Replica sollten stets temporär mit expliziter Deaktivierung dieser Variablen erfolgen und danach sofort rückgängig gemacht werden.
5Was ist der Unterschied zwischen gtid_executed und gtid_purged?
gtid_executed enthält alle Transaktionen, die ein Server jemals committet hat. gtid_purged ist die Teilmenge davon, deren Binlog-Einträge bereits physisch gelöscht wurden, aber weiterhin als bekannt geführt werden muss, damit spätere Auto-Position-Anfragen diese Transaktionen nicht erneut anfordern.
6Funktioniert GTID-Replikation mit Multi-Source-Setups?
Ja, allerdings muss die Eindeutigkeit der Server-UUID über alle Kanäle hinweg gewährleistet bleiben. Geklonte Instanzen mit identischer UUID sind eine häufige Fehlerquelle, insbesondere nach dem Start aus einem Snapshot ohne anschließendes Zurücksetzen und Neuerzeugen der UUID.
7Muss ich nach einem Restore aus einem Backup etwas Besonderes beachten?
Ja, gtid_purged muss auf dem Zielserver explizit gesetzt werden, damit spätere Auto-Position-Anfragen wissen, welche Transaktionen bereits im Backup enthalten waren. Sowohl mysqldump mit set-gtid-purged=ON als auch XtraBackup schreiben diese Information automatisch, sie darf beim Restore aber nicht ignoriert werden.
8Ersetzt SOURCE_AUTO_POSITION vollständig die manuelle Positionsermittlung?
Ja, sobald GTIDs überall aktiv sind, entfällt die Angabe von Logdatei und Byte-Position vollständig. Der Server berechnet die fehlende Transaktionsmenge selbst und meldet einen klaren Fehler, statt stillschweigend an der falschen Stelle weiterzumachen.
9Wie überwache ich, ob ein Replica wirklich synchron ist?
Am präzisesten über eine GTID_SUBTRACT-Abfrage zwischen Retrieved_Gtid_Set und Executed_Gtid_Set, die die tatsächliche Anzahl noch offener Transaktionen liefert. Diese Zahl ist genauer als die oft ungenaue Sekunden-Schätzung in Seconds_Behind_Source, besonders bei paralleler Replikation.
10Ist GTID-Replikation mit MyISAM-Tabellen möglich?
Technisch ja, allerdings schränkt enforce_gtid_consistency bestimmte gemischte Statements über transaktionale und nicht-transaktionale Engines ein. Für produktive Umgebungen empfiehlt sich durchgehend InnoDB, um Kompatibilitätsprobleme mit GTID-Konsistenzregeln von vornherein zu vermeiden.