Zum Inhalt springen
EuroVPSEuroVPS

Seconds_Behind_Master ist kein Gesundheitscheck für Replikate

Warum der Replikationsrückstand allein sagen kann, dass ein Replikat in Ordnung ist, obwohl es das nicht ist, und wie Sie MySQL- und MariaDB-Replikate mit GTID, Heartbeat, Checksum und Verbindungsrichtung prüfen.

Von EuroVPS Engineering

5 Min. Lesezeit
Seconds_Behind_Master is not a replica health check

Das Replikat, aus dem Sie wiederherstellen würden, ist nur dann etwas wert, wenn es aktuell, konsistent und außerhalb der Reichweite eines Angreifers ist. Das meiste Monitoring prüft eine Zahl, den Replikationsrückstand, und diese Zahl kann auf einem Replikat null anzeigen, das vor einer Stunde aufgehört hat, Änderungen zu empfangen. So prüfen Sie ein MySQL- oder MariaDB-Replikat, damit die Antwort etwas bedeutet.

Das Problem mit der Rückstandszahl

Seconds_Behind_Master (oder Seconds_Behind_Source in neuerem MySQL) wird vom SQL-Thread des Replikats berechnet: die Differenz zwischen dem Zeitstempel des Ereignisses, das er gerade anwendet, und der aktuellen Zeit. Er weiß nichts über Ereignisse, die er nicht empfangen hat.

Wenn also der I/O-Thread, der Änderungen vom Primary holt, an einer halb offenen TCP-Verbindung hängt, arbeitet der SQL-Thread alles ab, was er bereits hat, und meldet 0. Das Replikat sieht perfekt aus. Dabei hat es aufgehört, sich zu bewegen. Die Zahl zeigt außerdem NULL, wenn die Replikation gestoppt ist, und viele Prüfungen behandeln NULL als «kein Rückstand».

Prüfung eins: beide Threads, und die Fehlerfelder

Der erste Test ist langweilig und fängt die meisten Probleme ab:

SHOW SLAVE STATUS\G      -- or SHOW REPLICA STATUS\G

Verlangen Sie Slave_IO_Running: Yes und Slave_SQL_Running: Yes (die Replica_-Namen in neuerem MySQL), und verlangen Sie, dass Last_IO_Error und Last_SQL_Error leer sind. Connecting beim I/O-Thread ist nicht «running», es ist ein Replikat, das seine Quelle nicht erreichen kann.

Setzen Sie außerdem ein kurzes slave_net_timeout (oder replica_net_timeout) zusammen mit MASTER_HEARTBEAT_PERIOD auf dem Replikationskanal. Der Primary sendet dann im Leerlauf Heartbeats, und eine tote Verbindung wird in Sekunden erkannt, statt den Standard-Netzwerk-Timeout abzuwarten.

Prüfung zwei: Positionen vergleichen, nicht Zeitstempel

Mit GTID-Replikation hat jede committete Transaktion eine Kennung, und Sie können direkt vergleichen, wo der Primary steht und wo das Replikat steht.

Auf MariaDB:

-- on the primary
SELECT @@gtid_binlog_pos;
-- on the replica
SELECT @@gtid_slave_pos;

Auf MySQL vergleichen Sie @@gtid_executed auf beiden Seiten, oder fragen Sie das Replikat direkt, ob es eine Menge erreicht hat:

SELECT WAIT_FOR_EXECUTED_GTID_SET('<primary gtid_executed>', 5);

Wenn die Position des Primary weiter voranschreitet und die des Replikats nicht, haben Sie ein hängendes Replikat, was auch immer die Rückstandszahl sagt. Dieser Vergleich ist auch die Art, wie Sie ein Reseed oder einen Cutover abschließen: Beide Seiten müssen sich auf dieselbe Transaktion einigen, bevor jemand es für erledigt erklärt.

Prüfung drei: ein Heartbeat, den Sie selbst schreiben

Die ehrlichste Messung des Rückstands ist eine Zeile, die der Primary mit seiner eigenen Uhr aktualisiert und die auf dem Replikat zurückgelesen wird. pt-heartbeat aus dem Percona Toolkit macht genau das:

# on the primary, as a service
pt-heartbeat --update --database percona --create-table --daemonize
# on the replica, from monitoring
pt-heartbeat --check --database percona --master-server-id <id>

Weil die Messung durch die Replikation selbst reist, zeigt sich ein kaputter I/O-Thread als stetig wachsender Rückstand, und genau das wollten Sie von Anfang an sehen. Ein Testschreibvorgang auf dem Primary, gefolgt von einem Lesevorgang auf dem Replikat, liefert denselben Beweis von Hand, und er ist die schnellste Abnahmeprüfung für ein neues Replikat.

Prüfung vier: Sind die Daten tatsächlich gleich?

Replikation kann munter über Daten laufen, die auseinandergedriftet sind, nach einem Statement, das sich auf jeder Seite anders verhält, einem versehentlichen Schreibvorgang auf dem Replikat oder einem Tabellentyp, der nicht sicher repliziert. pt-table-checksum berechnet Checksums in Blöcken auf dem Primary und lässt die Replikation sie zum Replikat tragen, dann meldet es die Tabellen, die abweichen:

pt-table-checksum --replicate=percona.checksums --no-check-binlog-format h=<primary>

Lassen Sie es nach einem Zeitplan laufen, der zu Ihrem Schreibvolumen passt, außerhalb der Spitzenzeiten. Setzen Sie read_only = ON auf jedem Replikat (und super_read_only = ON auf MySQL), damit nichts, auch nicht das Werkzeug eines Administrators, versehentlich darauf schreiben kann.

Prüfung fünf: in welche Richtung die Verbindung geht

Diese hat mit Rückstand gar nichts zu tun. Ein Replikat ist Ihre Wiederherstellungskopie, also sollte es die Seite sein, die die Verbindung aufbaut. Das Replikat öffnet die Replikationsverbindung zum Primary. Der Primary sollte überhaupt keinen Netzwerkpfad zum Replikat haben.

Testen Sie das, statt es anzunehmen. Vom Primary aus:

nc -vz -w 3 <replica-address> 3306

Das sollte in einen Timeout laufen. Wenn es verbindet, kann ein Angreifer, der Ihren Produktionsserver übernommen hat, auch die Kopie erreichen, aus der Sie wiederherstellen wollen. Wir erzwingen die Richtung auf den Firewall-Appliances, nicht auf den Hosts, und beweisen sie bei jedem Build.

Alarmieren Sie bei Zustandswechseln, nicht bei jeder Messung

Fassen Sie alles oben zu einem Zustand pro Replikat zusammen: OK, LAGGING (über einem vereinbarten Schwellwert) oder BROKEN (ein Thread steht, ein Fehler ist gesetzt, oder die GTID-Position ist eingefroren, während der Primary sich bewegt). Alarmieren Sie dann nur, wenn der Zustand wechselt, einschließlich des Wechsels zurück zu OK.

state=$(replica_state)          # your check, returns OK, LAGGING or BROKEN
last=$(cat /var/lib/replcheck/state 2>/dev/null)
if [ "$state" != "$last" ]; then
  notify "replica: $last -> $state"
  echo "$state" > /var/lib/replcheck/state
fi

Lassen Sie das alle paar Minuten per Timer laufen. Die Ingenieure bekommen eine Nachricht, wenn sich etwas ändert, und eine, wenn es sich erholt, keinen Strom, den sie zu ignorieren lernen. Das eigentliche Risiko bei Replikaten ist nicht der Rückstand. Es ist ein Replikat, das vor Wochen stehen geblieben ist, ohne dass es jemand bemerkt hat.

Reseed ohne Raterei

Wenn ein Replikat tatsächlich neu aufgebaut werden muss, nimmt GTID Ihnen die Jagd nach Binary-Log-Koordinaten ab. Ein konsistenter logischer Dump mit eingebetteter Position, oder ein physisches Backup mit Mariabackup oder Percona XtraBackup, gibt Ihnen die exakte Transaktion, bei der Sie beginnen. Auf MariaDB reduziert sich die Seite des Replikats auf:

SET GLOBAL gtid_slave_pos = '<position from the dump or backup>';
CHANGE MASTER TO MASTER_HOST='<primary>', MASTER_USER='repl',
  MASTER_PASSWORD='<secret>', MASTER_USE_GTID=slave_pos;
START SLAVE;

Dann lassen Sie die Prüfungen eins bis drei erneut laufen und nehmen nicht ab, bevor beide Seiten nach einem Testschreibvorgang dieselbe GTID melden.

Ihre Checkliste

  • Beide Replikationsthreads laufen, Fehlerfelder leer, eine Heartbeat-Periode auf dem Kanal gesetzt.
  • GTID-Positionen von Primary und Replikat verglichen, nicht nur die Rückstandszahl.
  • Eine Heartbeat-Zeile oder ein Testschreibvorgang, der beweist, dass Änderungen tatsächlich ankommen.
  • Geplante Checksums, und read_only auf jedem Replikat.
  • Der Primary kann keine Verbindung zum Replikat öffnen, bewiesen vom Primary aus.
  • Alarme bei Zustandswechseln, damit ein hängendes Replikat innerhalb von Minuten eine Nachricht ist, keine Entdeckung an dem Tag, an dem Sie es brauchen.

Wenn Sie ein zweites Paar Augen auf Ihren Replikaten möchten, ist das die Art von Arbeit, die uns Freude macht.

Mit einem Ingenieur sprechen

Verwandt: Datenbankreplikation und Offsite-Replikate · Geclusterte Datenbanken mit Percona XtraDB Cluster · Managed Rechenzentrumsmigrationen, geprobt

Veröffentlicht am 8. Oktober 2026.

Alle Notizen aus der Praxis