MySQL-Slaves können inkonsistent werden. Sie können versuchen, es zu vermeiden, aber es ist wirklich schwierig. Das Festlegen von super_read_only und die Verwendung der zeilenbasierten Replikation können sehr hilfreich sein, aber egal, was Sie tun, es ist immer noch möglich, dass Ihr Slave inkonsistent wird.
Was kann getan werden, um einen inkonsistenten MySQL-Slave wieder aufzubauen? In diesem Blogbeitrag werden wir uns dieses Problem ansehen.
Lassen Sie uns zunächst besprechen, was passieren muss, um einen Sklaven wieder aufzubauen. Um einen Knoten in die MySQL-Replikation zu bringen, muss er mit Daten von einem der Knoten in der Replikationstopologie versorgt werden. Diese Daten müssen zum Zeitpunkt ihrer Erhebung konsistent sein. Sie können es nicht auf einer Tabelle-für-Tabelle- oder Schema-für-Schema-Basis nehmen, da dies den bereitgestellten Knoten intern inkonsistent machen würde. Das heißt, einige Daten wären älter als ein anderer Teil des Datensatzes.
Neben der Datenkonsistenz sollte es auch möglich sein, Informationen über die Beziehung zwischen den Daten und dem Stand der Replikation zu sammeln. Sie möchten entweder die Binärlog-Position haben, an der die gesammelten Daten konsistent sind, oder die globale Transaktions-ID der Transaktion, die zuletzt auf dem Knoten ausgeführt wurde, der die Quelle der Daten ist.
Das führt uns zu folgenden Überlegungen. Sie können einen Slave mit einem beliebigen Backup-Tool neu erstellen, solange dieses Tool konsistente Backups erstellen kann und Replikationskoordinaten für den Zeitpunkt enthält, zu dem das Backup konsistent ist. Dadurch können wir aus mehreren Optionen auswählen.
Mysqldump verwenden, um einen inkonsistenten MySQL-Slave neu aufzubauen
Mysqldump ist das grundlegendste Werkzeug, das wir haben, um dies zu erreichen. Es ermöglicht uns, eine logische Sicherung unter anderem in Form von SQL-Anweisungen zu erstellen. Was wichtig ist, obwohl es einfach ist, ermöglicht es uns dennoch, ein konsistentes Backup zu erstellen:Es kann Transaktionen verwenden, um sicherzustellen, dass die Daten zu Beginn der Transaktion konsistent sind. Es kann auch die Replikationskoordinaten für diesen Punkt aufschreiben, sogar eine ganze CHANGE MASTER-Anweisung, was es einfach macht, die Replikation unter Verwendung der Sicherung zu starten.
Mit Mydumper einen inkonsistenten MySQL-Slave neu erstellen
Eine weitere Möglichkeit ist die Verwendung von mydumper - dieses Tool erstellt, genau wie mysqldump, ein logisches Backup und kann, genau wie mysqldump, verwendet werden, um ein konsistentes Backup der Datenbank zu erstellen. Der Hauptunterschied zwischen mydumper und mysqldump besteht darin, dass mydumper, wenn es mit myloader gekoppelt ist, Daten parallel ausgeben und wiederherstellen kann, wodurch der Auszug und insbesondere die Wiederherstellungszeit verbessert werden.
Einen Snapshot verwenden, um einen inkonsistenten MySQL-Slave neu aufzubauen
Für diejenigen, die Cloud-Anbieter verwenden, besteht die Möglichkeit, einen Snapshot des zugrunde liegenden Blockspeichers zu erstellen. Snapshots erzeugen eine Point-in-Time-Ansicht der Daten. Dieser Prozess ist jedoch ziemlich knifflig, da die Konsistenz der Daten und die Fähigkeit, sie wiederherzustellen, hauptsächlich von der MySQL-Konfiguration abhängt.
Sie sollten sicherstellen, dass die Datenbank in einem dauerhaften Modus arbeitet (sie ist so konfiguriert, dass ein Absturz von MySQL nicht zu Datenverlust führt). Dies liegt daran, dass (aus MySQL-Sicht) das Erstellen eines Datei-Überblicks und das anschließende Starten einer weiteren MySQL-Instanz mit den darin gespeicherten Daten im Grunde der gleiche Vorgang ist, als ob Sie mysqld mit -9 beenden und dann erneut starten würden. Die InnoDB-Wiederherstellung muss stattfinden, Transaktionen wiedergeben, die in Binärprotokollen gespeichert wurden, Transaktionen zurücksetzen, die vor dem Absturz nicht abgeschlossen wurden, und so weiter.
Der Nachteil des Snapshot-basierten Wiederherstellungsprozesses ist, dass er stark an den aktuellen Anbieter gebunden ist. Sie können die Snapshot-Daten nicht einfach von einem Cloud-Anbieter zu einem anderen kopieren. Sie können es möglicherweise zwischen verschiedenen Regionen verschieben, aber es wird immer noch derselbe Anbieter sein.
Ein Xtrabackup oder Mariabackup verwenden, um einen inkonsistenten MySQL-Slave neu aufzubauen
Schließlich xtrabackup/mariabackup - dies ist ein von Percona geschriebenes und von MariaDB geforktes Tool, das es ermöglicht, ein physisches Backup zu erstellen. Es ist viel schneller als logische Backups – es wird hauptsächlich durch die Hardwareleistung begrenzt – Festplatte oder Netzwerk sind die wahrscheinlichsten Engpässe. Der größte Teil der Arbeitslast bezieht sich auf das Kopieren von Dateien aus dem MySQL-Datenverzeichnis an einen anderen Speicherort (auf demselben Host oder über das Netzwerk).
Obwohl nicht annähernd so schnell wie Blockspeicher-Snapshots, ist xtrabackup viel flexibler und kann in jeder Umgebung verwendet werden. Das erstellte Backup besteht aus Dateien, daher ist es durchaus möglich, das Backup an einen beliebigen Ort zu kopieren. Ein anderer Cloud-Anbieter, Ihr lokales Rechenzentrum, spielt keine Rolle, solange Sie Dateien von Ihrem aktuellen Standort übertragen können.
Es muss nicht einmal eine Netzwerkverbindung vorhanden sein - Sie können das Backup auch einfach auf ein "übertragbares" Gerät wie eine USB-SSD oder sogar einen USB-Stick kopieren, solange es alle Daten enthalten kann Daten und speichern Sie sie in Ihrer Tasche, während Sie von einem Rechenzentrum in ein anderes umziehen.
Wie erstellt man einen MySQL-Slave mit Xtrabackup neu?
Wir haben uns entschieden, uns auf xtrabackup zu konzentrieren, aufgrund seiner Flexibilität und Fähigkeit, in den meisten Umgebungen zu funktionieren, in denen MySQL existieren kann. Wie baut man seinen Slave mit xtrabackup wieder auf? Schauen wir uns das mal an.
Anfangs haben wir einen Master und einen Slave, die unter einigen Replikationsproblemen litten:
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.141
Master_User: rpl_user
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 386
Relay_Log_File: relay-bin.000008
Relay_Log_Pos: 363
Relay_Master_Log_File: binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1007
Last_Error: Error 'Can't create database 'mytest'; database exists' on query. Default database: 'mytest'. Query: 'create database mytest'
Skip_Counter: 0
Exec_Master_Log_Pos: 195
Relay_Log_Space: 756
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'mytest'; database exists' on query. Default database: 'mytest'. Query: 'create database mytest'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1001
Master_UUID: 53d96192-53f7-11ea-9c3c-080027c5bc64
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 200306 11:47:42
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:9
Executed_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:1-8,
ce7d0c38-53f7-11ea-9f16-080027c5bc64:1-3
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
Wie Sie sehen können, gibt es ein Problem mit einem der Schemas. Nehmen wir an, wir müssen diesen Knoten neu erstellen, um ihn wieder in die Replikation zu bringen. Hier sind die Schritte, die wir ausführen müssen.
Zuerst müssen wir sicherstellen, dass xtrabackup installiert ist. In unserem Fall verwenden wir MySQL 8.0, daher müssen wir xtrabackup in Version 8 verwenden, um die Kompatibilität zu gewährleisten:
[email protected]:~# apt install percona-xtrabackup-80
Reading package lists... Done
Building dependency tree
Reading state information... Done
percona-xtrabackup-80 is already the newest version (8.0.9-1.bionic).
0 upgraded, 0 newly installed, 0 to remove and 143 not upgraded.
Xtrabackup wird vom Percona-Repository bereitgestellt und die Anleitung zur Installation finden Sie hier:
https://www.percona.com/doc/percona-xtrabackup/8.0/installation/apt_repo.html
Das Tool muss sowohl auf dem Master als auch auf dem Slave installiert sein, den wir umbauen wollen.
Als nächsten Schritt entfernen wir alle Daten vom „kaputten“ Slave:
[email protected]:~# service mysql stop
[email protected]:~# rm -rf /var/lib/mysql/*
Als nächstes nehmen wir das Backup auf den Master und streamen es zum Slave. Bitte denken Sie daran, dass dieser spezielle Einzeiler eine passwortlose SSH-Root-Konnektivität vom Master zum Slave erfordert:
[email protected]:~# xtrabackup --backup --compress --stream=xbstream --target-dir=./ | ssh [email protected] "xbstream -x --decompress -C /var/lib/mysql/"
Am Ende sollten Sie eine wichtige Zeile sehen:
200306 12:10:40 completed OK!
Dies ist ein Indikator dafür, dass die Sicherung erfolgreich abgeschlossen wurde. Ein paar Dinge können immer noch schief gehen, aber zumindest haben wir die richtigen Daten. Als nächstes müssen wir auf dem Slave das Backup vorbereiten.
[email protected]:~# xtrabackup --prepare --target-dir=/var/lib/mysql/
.
.
.
200306 12:16:07 completed OK!
Sie sollten wieder sehen, dass der Vorgang erfolgreich abgeschlossen wurde. Möglicherweise möchten Sie die Daten jetzt zurück in das MySQL-Datenverzeichnis kopieren. Das müssen wir nicht tun, da wir das Streaming-Backup direkt in /var/lib/mysql gespeichert haben. Was wir jedoch tun möchten, ist sicherzustellen, dass die Dateien korrekt sind:
[email protected]:~# chown -R mysql.mysql /var/lib/mysql
Lassen Sie uns nun die GTID-Koordinaten des Backups überprüfen. Wir werden sie später beim Einrichten der Replikation verwenden.
[email protected]:~# cat /var/lib/mysql/xtrabackup_binlog_info
binlog.000007 195 53d96192-53f7-11ea-9c3c-080027c5bc64:1-9
Ok, alles scheint gut zu sein, lass uns MySQL starten und mit der Konfiguration der Replikation fortfahren:
[email protected]:~# service mysql start
[email protected]:~# mysql -ppass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18-9 Percona Server (GPL), Release '9', Revision '53e606f'
Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Jetzt müssen wir die gtid_purged auf den GTID-Satz setzen, den wir im Backup gefunden haben. Das sind GTIDs, die von unserem Backup „überdeckt“ wurden. Nur die neue GTID sollte vom Master repliziert werden.
mysql> SET GLOBAL gtid_purged='53d96192-53f7-11ea-9c3c-080027c5bc64:1-9';
Query OK, 0 rows affected (0.00 sec)
Now we can start the replication:
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.141', MASTER_USER='rpl_user', MASTER_PASSWORD='yIPpgNE4KE', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.141
Master_User: rpl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000007
Read_Master_Log_Pos: 380
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 548
Relay_Master_Log_File: binlog.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 380
Relay_Log_Space: 750
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1001
Master_UUID: 53d96192-53f7-11ea-9c3c-080027c5bc64
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:10
Executed_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:1-10
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
Wie Sie sehen können, repliziert unser Slave von seinem Master.
Wie erstellt man einen MySQL-Slave mit ClusterControl neu?
Wenn Sie ein ClusterControl-Benutzer sind, können Sie, anstatt diesen Prozess zu durchlaufen, den Slave mit nur wenigen Klicks neu erstellen. Zunächst haben wir ein klares Problem mit der Replikation:
Unser Slave repliziert aufgrund eines Fehlers nicht richtig.
Alles, was wir tun müssen, ist, den Job „Rebuild Replication Slave“ auszuführen .
Es wird Ihnen ein Dialogfeld angezeigt, in dem Sie einen Master-Knoten auswählen sollten der Sklave, den Sie umbauen möchten. Klicken Sie dann auf Fortfahren und schon sind Sie fertig. ClusterControl baut den Slave neu und richtet die Replikation für Sie ein.
In Kürze, basierend auf der Größe des Datensatzes, sollten Sie Working Slave:
sehenWie Sie sehen können, hat ClusterControl mit nur wenigen Klicks die Aufgabe erledigt, den inkonsistenten Replikations-Slave neu aufzubauen.