In diesem Blogpost werden wir untersuchen, wie eine Online-Migration von einem eigenständigen MySQL 5.6-Setup zu einem neuen Replikationssatz durchgeführt wird, der auf MySQL 5.7 läuft und von ClusterControl bereitgestellt und verwaltet wird.
Es ist geplant, einen Replikationslink vom neuen Cluster, der auf MySQL 5.7 läuft, zum Master einzurichten, der auf MySQL 5.6 läuft (außerhalb der ClusterControl-Bereitstellung), der keine GTID verwendet. MySQL unterstützt nicht das Mischen von GTID und Nicht-GTID in einer Replikationskette. Wir müssen also einige Tricks anwenden, um während der Migration zwischen Nicht-GTID- und GTID-Modi umzuschalten.
Unsere Architektur und unser Migrationsplan können wie folgt dargestellt werden:
Das Setup besteht aus 4 Servern, mit folgender Darstellung:
- mysql56a - Alter Meister - Oracle MySQL 5.6 ohne GTID
- Slave-Cluster:
- mysql57a – Neuer Master – Oracle MySQL 5.7 mit GTID
- mysql57b – Neuer Slave – Oracle MySQL 5.7 mit GTID
- cc - ClusterControl Server - Bereitstellungs-/Verwaltungs-/Überwachungsserver für die Datenbankknoten.
Alle MySQL 5.7-Hosts laufen auf Debian 10 (Buster), während MySQL 5.6 auf Debian 9 (Stretch) läuft.
Bereitstellen des Slave-Clusters
Lassen Sie uns zunächst den Slave-Cluster vorbereiten, bevor wir einen Replikationslink vom alten Master einrichten. Die endgültige Konfiguration des Slave-Clusters wird auf MySQL 5.7 mit aktiviertem GTID ausgeführt. Installieren Sie ClusterControl auf dem ClusterControl-Server (cc):
$ wget https://severalnines.com/downloads/install-cc
$ chmod 755 install-cc
$ ./install-cc
Folgen Sie den Anweisungen, bis die Installation abgeschlossen ist. Richten Sie dann passwortloses SSH von ClusterControl zu mysql57a und mysql57b ein:
$ whoami
root
$ ssh-keygen -t rsa # press Enter on all prompts
$ ssh-copy-id [email protected] # enter the target host root password
$ ssh-copy-id [email protected] # enter the target host root password
Melden Sie sich dann bei der ClusterControl-Benutzeroberfläche an, füllen Sie das Anfangsformular aus und gehen Sie zum Abschnitt ClusterControl -> Deploy -> MySQL Replication und füllen Sie Folgendes aus:
Klicken Sie dann auf Weiter und wählen Sie Oracle als Anbieter und 5.7 als Anbieter aus Ausführung. Fahren Sie dann mit dem Topologieabschnitt fort und konfigurieren Sie ihn wie folgt:
Warten Sie, bis die Bereitstellung abgeschlossen ist und Sie den neuen Cluster wie unten sehen sollten:
Unser Slave-Cluster, der auf MySQL 5.7 mit GTID läuft, ist jetzt fertig.
Vorbereitung des alten Meisters
Der aktuelle Master, den wir replizieren möchten, ist ein eigenständiges MySQL 5.6 (binäres Protokoll aktiviert, Server-ID konfiguriert, ohne GTID) und bedient Produktionsdatenbanken. Ausfallzeiten sind also keine Option für diese Migration. Andererseits konfiguriert ClusterControl das neue MySQL 5.7 mit aktiviertem GTID, was bedeutet, dass wir die GTID-Funktionalität innerhalb des Slave-Clusters deaktivieren müssen, um von diesem eigenständigen Master korrekt replizieren zu können.
Die folgenden Zeilen zeigen unsere aktuelle replikationsbezogene Konfiguration für den Master /etc/mysql/mysql.conf.d/mysqld.cnf unter der [mysqld]-Direktive:
server_id=1
binlog_format=ROW
log_bin=binlog
log_slave_updates=1
relay_log=relay-bin
expire_logs_days=7
sync_binlog=1
Vergewissern Sie sich, dass der MySQL-Server ein Binärprotokoll ohne GTID erzeugt:
mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000007 | 734310 | | | |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
Für Nicht-GTID wird erwartet, dass Executed_Gtid_Set leer ist. Beachten Sie, dass unser neuer MySQL 5.7-Replikationscluster, der von ClusterControl bereitgestellt wird, mit aktivierter GTID konfiguriert ist.
1) Erstellen Sie einen Replikationsbenutzer, der von mysql57a verwendet werden soll:
mysql> CREATE USER 'slave'@'192.168.10.31' IDENTIFIED BY 'slavepassword';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@192.168.10.31';
2) Automatische ClusterControl-Wiederherstellung deaktivieren. Unter der ClusterControl-Benutzeroberfläche -> wählen Sie den Cluster aus -> stellen Sie sicher, dass der Auto Recovery-Cluster und -Knoten ausgeschaltet sind (rote Stromsymbole), wie im folgenden Screenshot gezeigt:
Wir möchten nicht, dass ClusterControl den Knoten während dieser Replikationskonfiguration wiederherstellt.
3) Jetzt müssen wir ein vollständiges mysqldump-Backup erstellen, da dies ein Hauptversions-Upgrade sein wird. Andere nicht blockierende Backup-Tools wie Percona Xtrabackup oder MySQL Enterprise Backup unterstützen keine Wiederherstellung auf eine andere Hauptversion. Wir müssen auch die aktuelle binäre Protokolldatei und Position mit dem Flag --master-data beibehalten:
$ mysqldump -u root -p --single-transaction --master-data=2 --all-databases > mysql56a-fullbackup.sql
Beachten Sie, dass der obige Befehl aufgrund von --single-transaction keine InnoDB-Tabellen blockiert. Wenn Sie also MyISAM-Tabellen haben, werden die Tabellen während der Dauer der Sicherungen blockiert, um die Konsistenz zu wahren.
4) Kopieren Sie das Backup von mysql56a nach mysql57a und mysql57b:
$ scp mysql56a-fullbackup.sql [email protected]:~
$ scp mysql56a-fullbackup.sql [email protected]:~
Vorbereiten des Slave-Clusters
In dieser Phase werden wir den Slave-Cluster so konfigurieren, dass er mit der Replikation vom alten Master mysql56a ohne GTID beginnt.
1) Beenden Sie die Replikation zwischen mysql57a und mysql57b, entfernen Sie alle Slave-bezogenen Anmeldeinformationen, die von ClusterControl konfiguriert wurden, und deaktivieren Sie den Schreibschutz auf mysql57b:
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
mysql> SET GLOBAL super_read_only = 0;
mysql> SET GLOBAL read_only = 0;
2) GTID auf mysql57a deaktivieren:
mysql> SET GLOBAL gtid_mode = 'ON_PERMISSIVE';
mysql> SET GLOBAL gtid_mode = 'OFF_PERMISSIVE';
mysql> SET GLOBAL gtid_mode = 'OFF';
mysql> SET GLOBAL enforce_gtid_consistency = 'OFF';
3) GTID auf mysql57b deaktivieren:
mysql> SET GLOBAL gtid_mode = 'ON_PERMISSIVE';
mysql> SET GLOBAL gtid_mode = 'OFF_PERMISSIVE';
mysql> SET GLOBAL gtid_mode = 'OFF';
mysql> SET GLOBAL enforce_gtid_consistency = 'OFF';
4) Stellen Sie das mysqldump-Backup auf mysql57a wieder her:
$ mysql -uroot -p < mysql56a-fullbackup.sql
5) Stellen Sie das mysqldump-Backup auf mysql57b wieder her:
$ mysql -uroot -p < mysql56a-fullbackup.sql
6) Führen Sie das MySQL-Upgrade-Skript auf mysql57a aus (um alle Tabellen zu prüfen und auf die aktuelle Version zu aktualisieren):
$ mysql_upgrade -uroot -p
7) Führen Sie das MySQL-Upgrade-Skript auf mysql57b aus (um alle Tabellen zu überprüfen und auf die aktuelle Version zu aktualisieren):
$ mysql_upgrade -uroot -p
Beide Server auf dem Slave-Cluster werden jetzt mit dem Daten-Snapshot vom alten Master, mysql56a, bereitgestellt und sind jetzt zur Replikation bereit.
Replikation für den Slave-Cluster einrichten
1) Setzen Sie Binärlogs mit RESET MASTER auf mysql57a zurück, damit wir die Binärdatei und die Log-Positionierung später auf mysql57b nicht angeben müssen. Außerdem entfernen wir alle bestehenden GTID-Referenzen, die zuvor konfiguriert wurden:
mysql> RESET MASTER;
mysql> SET @@global.gtid_purged='';
2) Rufen Sie auf mysql57a die binlog-Datei und die Position aus der Speicherauszugsdatei mysql56a-fullbackup.sql ab:
$ head -100 mysql56a-fullbackup.sql | grep LOG_POS
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000007', MASTER_LOG_POS=4677987;
3) Starten Sie den Replikations-Slave vom alten Master mysql56a zum neuen Master mysql57a, indem Sie die korrekten MASTER_LOG_FILE- und MASTER_LOG_POS-Werte angeben, die im vorherigen Schritt abgerufen wurden. Auf mysql57a:
mysql> CHANGE MASTER TO MASTER_HOST = '192.168.10.22', MASTER_USER = 'slave', MASTER_PASSWORD = 'slavepassword', MASTER_LOG_FILE='binlog.000007', MASTER_LOG_POS=4677987;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
Stellen Sie sicher, dass Sie die folgenden Zeilen sehen:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Sie müssen wahrscheinlich warten, bis mysql57a mysql56a einholt, indem Sie "Seconds_Behind_Master" überwachen und sicherstellen, dass es 0 wird.
4) An diesem Punkt repliziert mysql57a Daten von mysql56a, was bedeutet, dass alle von ClusterControl erstellten Benutzer jetzt auf dem Server fehlen (weil mysql57a jetzt den Daten auf mysql56a folgt). ClusterControl wird ein Problem haben, sich mit mysql57a zu verbinden, und es wird als "down" angezeigt. Dies bedeutet im Grunde, dass ClusterControl keine Verbindung zu den MySQL-Servern herstellen kann, da die Genehmigungen fehlen. Die fehlenden Benutzer sind:
- [email protected]
- [email protected]'{alle Knoten in einem bestimmten Cluster}'
- [email protected]'{ClusterControl-Host}'
Alle Anmeldedaten werden sicher im ClusterControl und dem Datenbankserver selbst gespeichert. Sie benötigen Root-Zugriff, um die Anmeldeinformationen aus den relevanten Dateien abzurufen.
Lassen Sie uns nun die fehlenden Benutzer auf dem neuen Master mysql57a neu erstellen:
a) Backup-Benutzer erstellen (Passwort aus /etc/mysql/secrets-backup.cnf auf mysql57a):
mysql> CREATE USER [email protected] IDENTIFIED BY '[email protected]!65%JlNB1z';
mysql> GRANT RELOAD, LOCK TABLES, PROCESS, SUPER, REPLICATION CLIENT ON *.* TO [email protected];
b) Erstellen Sie Replikationsbenutzer für alle DB-Hosts (Passwort aus der Variable repl_password in /etc/cmon.d/cmon_X.cnf auf dem ClusterControl-Server, wobei X die Cluster-ID des Slave-Clusters ist):
mysql> CREATE USER 'rpl_user'@'192.168.10.31' IDENTIFIED BY '68n61F+bdsW1}[email protected]}x5J';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'192.168.10.31';
mysql> CREATE USER 'rpl_user'@'192.168.10.32' IDENTIFIED BY '68n61F+bdsW1}[email protected]}x5J';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'192.168.10.32';
c) Erstellen Sie zwei cmon-Datenbankbenutzer (einen für die IP-Adresse und einen für den Hostnamen) für die ClusterControl-Nutzung (Passwort aus der mysql_password-Variable in /etc/cmon.d/cmon_X.cnf auf dem ClusterControl-Server, wobei X die Cluster-ID des Slaves ist Cluster):
mysql> CREATE USER [email protected]'192.168.10.19' IDENTIFIED BY 'My&Passw0rd90';
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.10.19' WITH GRANT OPTION;
mysql> CREATE USER [email protected]'cc.local' IDENTIFIED BY 'My&Passw0rd90';
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'cc.local' WITH GRANT OPTION;
5) An dieser Stelle sollte mysql57a in ClusterControl grün erscheinen. Jetzt können wir einen Replikationslink von mysql57a zu mysql57b einrichten. Auf mysql57b:
mysql> RESET MASTER;
mysql> SET @@global.gtid_purged='';
mysql> CHANGE MASTER TO MASTER_HOST = '192.168.10.31', MASTER_USER = 'rpl_user', MASTER_PASSWORD = '68n61F+bdsW1}[email protected]}x5J';
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
**Wir brauchen MASTER_LOG_FILE und MASTER_LOG_POS nicht anzugeben, da es immer mit einer festen Anfangsposition nach RESET MASTER bei Schritt #1 beginnt.
Stellen Sie sicher, dass die folgenden Zeilen angezeigt werden:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Überwachen Sie den Replikationsstatus und stellen Sie sicher, dass mysql57b mit mysql57a und mysql57a mit mysql56a Schritt hält. Möglicherweise müssen Sie danach den Schreibschutz für mysql57b (und/oder mysql57a) aktivieren, um sich vor versehentlichem Schreiben zu schützen.
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Von der ClusterControl-Benutzeroberfläche sehen Sie den aktuellen Status im Abschnitt "Übersicht":
Zu diesem Zeitpunkt repliziert der neue Master mysql57a, 192.168.10.31 der alte eigenständige Host mysql56a, 192.168.10.22, während der neue Slave mysql57b (schreibgeschützt) von mysql57a, 192.168.10.31 repliziert. Alle Knoten werden mit der Replikationsverzögerung 0 synchronisiert.
Alternativ können Sie die folgenden Zeilen in den MySQL-Konfigurationsdateien im Abschnitt [mysqld] auskommentieren:
#gtid_mode=ON
#enforce_gtid_consistency=1
GTID auf dem Slave-Cluster aktivieren
Beachten Sie, dass ClusterControl für MySQL 5.6 und höher die Nicht-GTID-Implementierung einiger seiner Verwaltungsfunktionen wie Rebuild Replication Slave und Change Replication Master nicht mehr unterstützt. Während der Cutoff-Zeit (wenn Sie Anwendungen auf den neuen Cluster verweisen) vom eigenständigen MySQL-Server (mysql56a) wird empfohlen, GTID auf mysql57a und mysql57b mit den folgenden Schritten wieder zu aktivieren:
1) Stellen Sie sicher, dass die automatische Wiederherstellungsfunktion von ClusterControl deaktiviert ist:
2) Während des Cutoff-Wartungsfensters müssen wir die Replikation stoppen Entfernen Sie vom alten Master, mysql56a, alle Slave-Konfigurationen auf mysql57a und aktivieren Sie wieder GTID. Führen Sie auf mysql57a die folgenden Befehle in der richtigen Reihenfolge aus:
mysql> SHOW SLAVE STATUS\G # Make sure you see "Slave has read all relay log"
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
mysql> SET GLOBAL super_read_only = 0;
mysql> SET GLOBAL read_only = 0;
mysql> SET GLOBAL gtid_mode = 'OFF_PERMISSIVE';
mysql> SET GLOBAL gtid_mode = 'ON_PERMISSIVE';
mysql> SET GLOBAL enforce_gtid_consistency = 'ON';
mysql> SET GLOBAL gtid_mode = 'ON';
An diesem Punkt ist es für Ihre Anwendung praktisch sicher, mit dem Schreiben an den neuen Master, mysql57a, zu beginnen. Das alte eigenständige MySQL ist jetzt aus der Replikationskette entfernt und kann heruntergefahren werden.
3) Wiederholen Sie die gleichen Schritte für mysql57b. Denken Sie daran, die Schritte in der richtigen Reihenfolge auszuführen:
mysql> SHOW SLAVE STATUS\G # Make sure you see "Slave has read all relay log"
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
mysql> SET GLOBAL super_read_only = 0;
mysql> SET GLOBAL read_only = 0;
mysql> SET GLOBAL gtid_mode = 'OFF_PERMISSIVE';
mysql> SET GLOBAL gtid_mode = 'ON_PERMISSIVE';
mysql> SET GLOBAL enforce_gtid_consistency = 'ON';
mysql> SET GLOBAL gtid_mode = 'ON';
4) Setzen Sie dann den Master auf den neuen Master zurück, mysql57a:
mysql> RESET MASTER;
3) Dann richtet mysql57b auf dem neuen Slave den Replikationslink mit GTID zu mysql57a ein:
mysql> RESET MASTER;
mysql> CHANGE MASTER TO MASTER_HOST = '192.168.10.31', MASTER_USER = 'rpl_user', MASTER_PASSWORD = '68n61F+bdsW1}[email protected]}x5J', MASTER_AUTO_POSITION = 1;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
Stellen Sie sicher, dass die Felder Retrieved_Gtid_Set und Executed_Gtid_Set ihren GTID-Wert haben.
4) An diesem Punkt haben wir die Replikationskonfiguration so wiederhergestellt, wie sie zuvor von ClusterControl während der Clusterbereitstellungsphase konfiguriert wurde. Wir können dann auf dem neuen Slave mysql57b schreibgeschützt aktivieren, um ihn vor versehentlichem Schreiben zu schützen:
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Aktivieren Sie schließlich die automatische ClusterControl-Wiederherstellung für den Cluster erneut, indem Sie die Stromsymbole auf grün schalten. Anschließend können Sie den alten Master mysql56a außer Betrieb nehmen. Wir haben gerade unsere Online-Migration von MySQL 5.6 auf MySQL 5.7 mit sehr minimaler Ausfallzeit abgeschlossen. Die ähnlichen Schritte sollten auch für die Migration zu MySQL 8.0 funktionieren.