Rückstand im Replikat

Wenn die Replik nicht mehr hinterherkommt

Der Wert, den fast alle ablesen, ist der unzuverlässigste. Die belastbaren Zahlen stehen im Performance Schema, und sie zeigen auch, ob es an der Übertragung oder am Anwenden liegt.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Seit 1997 am Markt Kleine Gruppen Präsenz und Live-Online Zertifizierte Trainer
Worum es geht

Ein Rückstand fällt erst auf, wenn jemand veraltete Daten sieht

Repliken tragen im Alltag Leselast, Berichte und Sicherungen. Solange der Rückstand im Sekundenbereich bleibt, merkt das niemand. Wächst er auf Minuten, meldet der Fachbereich, dass eine gerade gespeicherte Änderung in der Auswertung fehlt, und die Ursachensuche beginnt an der falschen Stelle, nämlich in der Anwendung.

Ernst wird es, wenn die Replik als Ausweichsystem gedacht ist. Ein Rückstand von zwanzig Minuten bedeutet im Ernstfall zwanzig Minuten verlorene Schreibvorgänge, und diese Zahl steht in keinem Notfallkonzept, weil dort mit dem Zustand von der letzten Prüfung gerechnet wird. Der Rückstand gehört deshalb überwacht wie jede andere Betriebskennzahl.

Der teuerste Fehler ist Abwarten. Wenn die Replik dauerhaft weniger Änderungen anwenden kann, als die Quelle erzeugt, holt sie nie wieder auf, der Abstand wächst linear weiter. Wer das zu spät bemerkt, verliert zusätzlich die Möglichkeit zum Aufholen, weil die Quelle ihre Binärprotokolle inzwischen gelöscht hat und nur noch ein vollständiger Neuaufbau bleibt.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Symptom, Ursache, Lösung

Symptom, Ursache, Lösung

Symptom

Seconds_Behind_Source springt zwischen 0 und mehreren Minuten hin und her.

Ursache

Der Wert misst nur, wie weit der Anwenderprozess hinter dem liegt, was er bereits empfangen hat. Solange der Empfänger noch Ereignisse in die Warteschlange stellt, zeigt der Wert 0, danach plötzlich einen großen Abstand. Bei Ereignissen mit alten Zeitstempeln pendelt er entsprechend.

Lösung

Statt des Statusfelds die Zeitstempel aus dem Performance Schema nutzen. Die Differenz zwischen NOW() und APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP in replication_applier_status_by_worker ist der tatsächliche Rückstand gegenüber dem Ursprungsserver, auch in einer Kette aus mehreren Ebenen.

Symptom

Der Rückstand entsteht immer nachts zur selben Zeit und baut sich bis zum Vormittag wieder ab.

Ursache

Ein Aufräum- oder Archivierungsjob ändert Millionen Zeilen in einer einzigen Transaktion. Auf der Quelle verteilt sich das auf viele parallele Verbindungen, auf der Replik wird die Transaktion als ein Block angewendet, und alles danach wartet.

Lösung

Den Job in Blöcke zerlegen, etwa je zehntausend Zeilen mit einem eigenen COMMIT und einer kurzen Pause dazwischen. Das verlängert den Job auf der Quelle geringfügig und nimmt der Replik die Blockade vollständig.

Symptom

Vier Anwender-Worker sind konfiguriert, aber im Performance Schema arbeitet immer nur einer.

Ursache

Die Replik kann nur parallelisieren, wenn im Binärprotokoll steht, welche Transaktionen voneinander unabhängig sind. Diese Information erzeugt die Quelle. In MySQL 8.0 musste dafür binlog_transaction_dependency_tracking auf WRITESET gesetzt werden, ab 8.4 macht der Server das immer selbst.

Lösung

Auf einer Quelle mit MySQL 8.0 die Abhängigkeitsverfolgung auf WRITESET umstellen. Zusätzlich prüfen, ob replica_preserve_commit_order aktiv ist, denn die Bestätigungen erfolgen dann in der Reihenfolge der Quelle, was Parallelität einschränkt, aber die Lesekonsistenz erhält.

Symptom

Ein einzelnes UPDATE auf einer großen Tabelle hält die Replik minutenlang auf, obwohl es auf der Quelle schnell lief.

Ursache

Die Tabelle hat keinen Primärschlüssel und keinen eindeutigen Index ohne NULL-Werte. Bei zeilenbasierter Replikation muss die Replik jede zu ändernde Zeile anhand ihres vollständigen alten Inhalts wiederfinden und geht dafür die Tabelle durch. Auf der Quelle lief stattdessen ein einziger Indexzugriff.

Lösung

Der Tabelle einen Primärschlüssel geben. Findest du die betroffenen Tabellen nicht auf Anhieb, liefert ein Abgleich von information_schema.TABLES gegen information_schema.TABLE_CONSTRAINTS die Liste aller Tabellen ohne Primärschlüssel.

Symptom

Nach einem längeren Ausfall meldet die Replik, ein benötigtes Binärprotokoll sei nicht mehr vorhanden.

Ursache

Die Quelle hat die Protokolldateien nach Ablauf von binlog_expire_logs_seconds gelöscht. Der Punkt, an dem die Replik weitermachen müsste, liegt davor. Aufholen ist damit unmöglich, unabhängig von der Rechenleistung.

Lösung

Die Replik neu aufbauen, entweder über CLONE INSTANCE oder aus einer Sicherung mit der zugehörigen Position. Danach die Aufbewahrungsdauer der Binärprotokolle so setzen, dass sie die längste denkbare Ausfallzeit abdeckt, und den freien Platz dafür einplanen.

Sechs Ursachen für Rückstand, in der Reihenfolge der Prüfung

  1. 01 Eine einzelne große Transaktion wird als unteilbarer Block angewendet.
  2. 02 Eine Tabelle ohne Primärschlüssel zwingt die Replik zu vollen Durchläufen.
  3. 03 Die Abhängigkeitsinformation der Quelle erlaubt keine parallele Anwendung.
  4. 04 Die Replik hat weniger Arbeitsspeicher und liest deshalb ständig von Platte.
  5. 05 Lange Leseabfragen auf der Replik halten den Anwenderprozess auf.
  6. 06 Strenge Schreibsicherheitseinstellungen kosten je Transaktion einen Plattenzugriff.
Was du mitnimmst

Danach weißt du, ob die Übertragung oder das Anwenden klemmt

Die Diagnose läuft in zwei Stufen: erst die Trennung zwischen Empfang und Anwendung, dann die Suche nach der Bremse innerhalb der Anwendungsseite. Erst danach ist die Frage sinnvoll, ob mehr Parallelität hilft oder ob ein Neuaufbau schneller ist.

Den Rückstand belastbar messen

Statt Seconds_Behind_Source nimmst du die Zeitstempel aus performance_schema.replication_applier_status_by_worker. Die Differenz zwischen der aktuellen Uhrzeit und APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP ist der tatsächliche Rückstand.

Empfang und Anwendung trennen

replication_connection_status zeigt, was bereits in der Warteschlange liegt. Ist dort schon alles angekommen und der Anwenderprozess trotzdem im Rückstand, ist die Netzstrecke unschuldig und du suchst auf der Anwendungsseite weiter.

Große Einzeltransaktionen aufspüren

Eine Transaktion wird als Ganzes angewendet und lässt sich nicht aufteilen. Ein Aufräumjob, der eine Million Zeilen in einem Rutsch löscht, blockiert die Replik so lange, wie er auf der Quelle gedauert hat, und alles Nachfolgende wartet.

Tabellen ohne Primärschlüssel finden

Bei zeilenbasierter Replikation sucht die Replik jede zu ändernde Zeile. Ohne Primärschlüssel oder eindeutigen Index baut sie dafür eine Hashtabelle über die Zeilen des Zeilenereignisses auf und geht anschließend die gesamte Tabelle einmal durch. Ein Durchlauf je Zeilenereignis klingt harmlos, aber ein großes UPDATE zerfällt in viele solche Ereignisse, und aus einem Indexzugriff auf der Quelle werden auf der Replik entsprechend viele vollständige Tabellendurchläufe.

Prüfen, ob die Parallelität wirklich wirkt

Ob die Replik parallel arbeiten kann, entscheidet die Abhängigkeitsinformation im Binärprotokoll der Quelle, nicht die Zahl der Worker auf der Replik. Ab MySQL 8.4 erzeugt die Quelle diese Information immer, davor musste sie eingeschaltet werden.

Erkennen, wann Aufholen aussichtslos ist

Wenn der Rückstand über Stunden gleichmäßig wächst, liegt die Anwendungsleistung dauerhaft unter der Schreiblast. Dann ist ein Neuaufbau aus einer Kopie der schnellere Weg, und die Aufbewahrungsdauer der Binärprotokolle setzt dafür die Frist.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt

Den Rückstand richtig messen

Seconds_Behind_Source ist der Wert, den fast alle ablesen, und er ist mit Vorsicht zu genießen. Das Handbuch nennt die Fälle selbst: Er kann 0 zeigen, obwohl die Netzverbindung zur Quelle abgerissen ist und der Empfänger es noch nicht bemerkt hat. Er zeigt 0, solange der Anwenderprozess alles verarbeitet hat, was empfangen wurde, auch wenn auf der Quelle längst mehr passiert ist. Und bei Ereignissen mit alten Zeitstempeln wechselt er bei mehreren Aufrufen kurz hintereinander zwischen 0 und einem großen Wert.

Die belastbare Messung steht im Performance Schema. In replication_applier_status_by_worker liefert APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP den Zeitpunkt, zu dem die gerade angewendete Transaktion auf dem Ursprungsserver bestätigt wurde, LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP dasselbe für die zuletzt fertige. Die Differenz zur aktuellen Uhrzeit ist der Rückstand, und weil der Ursprungszeitstempel weitergereicht wird, stimmt er auch in einer mehrstufigen Kette.

Für die Trennung zwischen Empfang und Anwendung ist replication_connection_status zuständig. Dort steht, welche Transaktion zuletzt in die Warteschlange gestellt wurde und wann der letzte Lebenszeichen-Impuls von der Quelle kam. Liegt die zuletzt eingereihte Transaktion weit vor der zuletzt angewendeten, ist die Anwendungsseite die Bremse. Hinkt schon der Empfang hinterher, liegt es an Netz oder Bandbreite, und dort hilft die Komprimierung der Übertragung über binlog_transaction_compression auf der Quelle.

Warum eine Replik langsamer ist als die Quelle, obwohl die Hardware gleich ist

Auf der Quelle arbeiten hunderte Verbindungen gleichzeitig. Auf der Replik wird dieselbe Arbeit von einer begrenzten Zahl an Worker-Prozessen erledigt, und ob diese wirklich parallel arbeiten können, hängt daran, welche Abhängigkeitsinformationen im Binärprotokoll stehen. Genau hier sitzt der häufigste Denkfehler: Die entscheidende Einstellung liegt auf der Quelle, nicht auf der Replik.

In MySQL 8.0 musste dafür binlog_transaction_dependency_tracking auf der Quelle auf WRITESET gesetzt werden. Dann vermerkt der Server, welche Zeilen eine Transaktion berührt hat, und Transaktionen ohne Überschneidung dürfen auf der Replik gleichzeitig angewendet werden. Ohne diese Einstellung galt nur die Bestätigungsreihenfolge als Maßstab, und das reicht in einer Anwendung mit kurzen, sequenziellen Transaktionen kaum für Parallelität. Mit MySQL 8.4 hat Oracle die Variable entfernt und das Verhalten fest eingebaut, die Quelle erzeugt die Abhängigkeitsinformation seitdem immer.

Auf der Replikseite kommen replica_parallel_workers für die Zahl der Worker und replica_preserve_commit_order hinzu. Letzteres erzwingt, dass Transaktionen in derselben Reihenfolge bestätigt werden wie auf der Quelle. Das ist die Voraussetzung dafür, dass Lesevorgänge auf der Replik einen konsistenten Zustand sehen, kostet aber Parallelität, weil ein schneller Worker auf einen langsamen vor ihm warten muss.

Was jenseits der Replikation bremst

Repliken werden oft kleiner ausgestattet als die Quelle, weil sie ja nur nachvollziehen, was dort schon passiert ist. Der Denkfehler steckt im Pufferpool. Jedes Zeilenereignis muss die betroffene Seite finden, und wenn sie nicht im Speicher liegt, wird sie von der Platte gelesen. Auf der Quelle war dieselbe Seite warm, weil die Anwendung ohnehin darauf zugreift. Eine Replik mit halbem Arbeitsspeicher wendet deshalb nicht halb so schnell an, sondern deutlich langsamer.

Dazu kommt die Zweitnutzung. Läuft auf der Replik nachts die Sicherung und tagsüber der Berichtsbetrieb, konkurrieren beide mit dem Anwenderprozess um dieselbe Ein- und Ausgabe. Ein weiterer Hebel sind zwei Einstellungen für die Schreibsicherheit: sync_binlog und innodb_flush_log_at_trx_commit stehen für den sicheren Betrieb beide auf 1 und kosten damit je Transaktion einen erzwungenen Plattenzugriff. Auf 0 beziehungsweise 2 gesetzt, schafft die Replik deutlich mehr Transaktionen je Sekunde. Das ist eine bewusste Abwägung und keine Optimierung nebenbei, denn eine so eingestellte Replik kann nach einem harten Ausfall nicht mehr aufsetzen und muss neu aufgebaut werden.

Der Fall, den man nur mit einem Blick ins Schema findet

Zeilenbasierte Replikation überträgt für ein UPDATE oder DELETE den Zustand der Zeile vor und nach der Änderung. Auf der Replik muss die passende Zeile erst gefunden werden. Das Handbuch beschreibt den Ablauf klar: Gibt es einen Primärschlüssel oder einen eindeutigen Index, in dem alle Spalten NOT NULL sind, wird darüber zugegriffen. Fehlt beides, baut die Replik eine Hashtabelle über die zu ändernden Zeilen auf und geht anschließend die gesamte Tabelle durch.

Der Unterschied in der Laufzeit ist dramatisch. Auf der Quelle findet ein Indexzugriff die Zeile in wenigen Schritten, auf der Replik wird eine Tabelle mit Millionen Zeilen einmal komplett gelesen. Weil das für jedes Zeilenereignis geschieht, kann ein Vorgang, der auf der Quelle Sekunden brauchte, auf der Replik Stunden dauern.

Tabellen ohne Primärschlüssel sind selten Absicht, sie entstehen bei Zwischen- und Protokolltabellen, die jemand schnell angelegt hat. Ein Abgleich zwischen information_schema.TABLES und information_schema.TABLE_CONSTRAINTS zeigt sie. Bevor du einen Primärschlüssel ergänzt, prüf, ob die Tabelle überhaupt repliziert werden muss, denn oft ist die richtige Antwort, sie von der Replikation auszunehmen.

Wann ein Neuaufbau schneller ist als Aufholen

Die Entscheidung hängt an einer Beobachtung über die Zeit. Miss den Rückstand über eine Stunde in gleichmäßigen Abständen. Sinkt er, holt die Replik auf, und du kannst rechnen, wann sie fertig ist. Bleibt er gleich, arbeitet sie genau am Limit, und jede zusätzliche Last auf der Quelle vergrößert den Abstand wieder. Wächst er gleichmäßig, ist die Anwendungsleistung dauerhaft zu klein, und Warten ändert daran nichts.

Im dritten Fall ist der Neuaufbau der schnellere Weg. Mit der Anweisung CLONE INSTANCE kopiert MySQL eine vollständige Instanz auf einen neuen Server, einschließlich der Position, an der die Replikation weiterläuft. Alternativ dient eine physische Sicherung mit vermerkter Position als Ausgangspunkt. Beides ist in der Regel um Größenordnungen schneller, als Tage an Binärprotokollen nachzuspielen.

Die Frist dafür setzt die Aufbewahrungsdauer der Binärprotokolle auf der Quelle, gesteuert über binlog_expire_logs_seconds. Sind die Dateien gelöscht, die die Replik noch bräuchte, entfällt die Wahl und es bleibt nur der Neuaufbau. Deshalb gehört diese Einstellung zum Notfallkonzept: Sie muss die längste Ausfallzeit abdecken, mit der du rechnest, und der Plattenplatz dafür muss vorhanden sein.

Dazu passende Kurse

Wer ein Gespann aus Quelle und Replik verantwortet, braucht beide Seiten im Blick, und darauf zielen die MySQL-Kurse zu Replikation und Ausfallsicherheit .

Läuft bei dir stattdessen MariaDB, gelten eigene Kennungen und eine eigene Werkzeugkette, und dafür ist der Betrieb der MariaDB-Variante das passende Thema.

Wissen prüfen

Wie sicher bist du beim Thema wirklich?

Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.

Super Schulung, in der der Trainer auch auf eigene Fragestellungen eingegangen ist.
PostgreSQL Datenbankentwicklung Aufbaukurs
Super Grundlagenschulung mit allen wichtigen Punkten und hilfreichen Tipps!
PostgreSQL Einführung und SQL Grundlagenkurs
Schön, sich 5 Tage ungestört mit Postgres beschäftigen zu können.
PostgreSQL für Administratoren Grundkurs

Häufige Fragen

Hilft es, einfach mehr Worker auf der Replik einzustellen?
Nur wenn im Binärprotokoll überhaupt steht, welche Transaktionen unabhängig sind. Diese Information erzeugt die Quelle. Bei MySQL 8.0 gehört dafür die Abhängigkeitsverfolgung auf WRITESET gesetzt, ab 8.4 macht der Server das von sich aus. Ohne diese Grundlage laufen zusätzliche Worker leer, und du siehst im Performance Schema, dass immer nur einer arbeitet.
Kann ich die Replik schneller machen, indem ich die Schreibsicherheit lockere?
Ja, und es ist eine bewusste Abwägung. Eine Replik, die nur Leselast bedient, kann mit weniger strengen Einstellungen für das Schreiben von Protokolldateien deutlich mehr Transaktionen je Sekunde anwenden. Der Preis ist, dass sie nach einem harten Ausfall des Betriebssystems die letzten Transaktionen verlieren und neu aufgebaut werden muss. Für ein System, das im Notfall die Quelle ersetzen soll, ist das der falsche Handel.
Woran erkenne ich, ob es am Netz oder am Anwenden liegt?
Am Vergleich zweier Tabellen im Performance Schema. replication_connection_status zeigt, was der Empfänger bereits in die Warteschlange gestellt hat, replication_applier_status_by_worker, was davon angewendet wurde. Liegt der Empfang vorn und die Anwendung hinterher, ist die Anwendungsseite die Bremse. Hinkt schon der Empfang, geht es um Bandbreite oder Latenz.
Muss ich mir Sorgen machen, wenn der Rückstand kurz auf mehrere Minuten springt?
Nicht unbedingt. Ein einzelner großer Vorgang, etwa ein nächtlicher Import, erzeugt genau dieses Muster, und sobald er angewendet ist, verschwindet der Rückstand wieder. Beobachtungswürdig ist der Verlauf, nicht der Einzelwert: ein Ausschlag mit anschließendem Abbau ist normal, ein gleichmäßiges Ansteigen über Stunden nicht.
Persönlich für dich da

Deine Ansprechpartner

Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.

Yves Hoppe

Yves Hoppe

Weiterbildung & Beratung

Hilft dir, aus dem Datenbanken-Programm den passenden Kurs für deinen Stand zu finden.

Norbert Jansen

Norbert Jansen

Beratung & Inhouse

Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.

Replikation, die man messen kann statt zu vermuten

Wie eine Replik aufgesetzt, überwacht und im Ernstfall neu aufgebaut wird, arbeitest du bei cmt an einem laufenden Gespann durch, samt der Frage, welche Zahl im Notfallkonzept steht.