I det här blogginlägget kommer vi att undersöka hur man utför onlinemigrering från MySQL 5.6 fristående installation till en ny replikeringsuppsättning som körs på MySQL 5.7, distribuerad och hanterad av ClusterControl.
Planen är att sätta upp en replikeringslänk från det nya klustret som körs på MySQL 5.7 till mastern som körs på MySQL 5.6 (utanför ClusterControl-försörjningen), som inte använder något GTID. MySQL stöder inte blandning av GTID och icke-GTID i en replikeringskedja. Så vi måste göra några knep för att växla mellan icke-GTID- och GTID-lägen under migreringen.
Vår arkitektur och migrationsplan kan illustreras enligt nedan:
Inställningen består av 4 servrar, med följande representation:
- mysql56a - Old master - Oracle MySQL 5.6 utan GTID
- Slavkluster:
- mysql57a - Ny master - Oracle MySQL 5.7 med GTID
- mysql57b - Ny slav - Oracle MySQL 5.7 med GTID
- cc - ClusterControl Server - Server för distribution/hantering/övervakning för databasnoderna.
Alla MySQL 5.7-värdar körs på Debian 10 (Buster), medan MySQL 5.6 körs på Debian 9 (Stretch).
Distribuera slavklustret
Låt oss först förbereda slavklustret innan vi sätter upp en replikeringslänk från den gamla mastern. Den slutliga konfigurationen av slavklustret kommer att köras på MySQL 5.7, med GTID aktiverat. Installera ClusterControl på ClusterControl-servern (cc):
$ wget https://severalnines.com/downloads/install-cc
$ chmod 755 install-cc
$ ./install-cc
Följ instruktionerna tills installationen är klar. Ställ sedan in lösenordslös SSH från ClusterControl till mysql57a och mysql57b:
$ 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
Logga sedan in på ClusterControl UI, fyll i det första formuläret och gå till ClusterControl -> Deploy -> MySQL-replikering och fyll i följande:
Klicka sedan på Fortsätt och välj Oracle som leverantör och 5.7 som leverantör version. Fortsätt sedan till topologisektionen och konfigurera den enligt nedan:
Vänta tills distributionen är klar och du bör se det nya klustret enligt nedan:
Vårt slavkluster som körs på MySQL 5.7 med GTID är nu klart.
Förbereder den gamla mästaren
Den nuvarande mastern som vi vill replikera är en fristående MySQL 5.6 (binär logg aktiverad, server-id konfigurerad, utan GTID) och den betjänar produktionsdatabaser. Så stilleståndstid är inte ett alternativ för denna migrering. Å andra sidan konfigurerar ClusterControl den nya MySQL 5.7 med GTID-aktiverad vilket innebär att vi måste stänga av GTID-funktionalitet inuti slavklustret för att kunna replikera korrekt från denna fristående master.
Följande rader visar vår nuvarande replikeringsrelaterade konfiguration för master /etc/mysql/mysql.conf.d/mysqld.cnf under [mysqld]-direktivet:
server_id=1
binlog_format=ROW
log_bin=binlog
log_slave_updates=1
relay_log=relay-bin
expire_logs_days=7
sync_binlog=1
Verifiera att MySQL-servern producerar binär logg utan GTID:
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 icke-GTID förväntas Executed_Gtid_Set vara tom. Observera att vårt nya MySQL 5.7 replikeringskluster som distribueras av ClusterControl är konfigurerat med GTID aktiverat.
1) Skapa en replikeringsanvändare som ska användas av mysql57a:
mysql> CREATE USER 'slave'@'192.168.10.31' IDENTIFIED BY 'slavepassword';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@192.168.10.31';
2) Inaktivera ClusterControl automatisk återställning. Under ClusterControl UI -> välj klustret -> se till att Auto Recovery Cluster och Node är avstängda (röda strömikoner), som visas i skärmdumpen nedan:
Vi vill inte att ClusterControl ska återställa noden under denna replikeringskonfiguration.
3) Nu måste vi skapa en fullständig säkerhetskopia av mysqldump eftersom detta kommer att bli en större versionsuppgradering. Andra icke-blockerande säkerhetskopieringsverktyg som Percona Xtrabackup eller MySQL Enterprise Backup stöder inte återställning till en annan huvudversion. Vi måste också bevara den nuvarande binära loggfilen och positionen med hjälp av --master-data flagga:
$ mysqldump -u root -p --single-transaction --master-data=2 --all-databases > mysql56a-fullbackup.sql
Observera att kommandot ovan inte blockerar några InnoDB-tabeller på grund av --single-transaction. Så om du har MyISAM-tabeller kommer tabellerna att blockeras under säkerhetskopieringsperioden för att bibehålla konsekvens.
4) Kopiera säkerhetskopian från mysql56a till mysql57a och mysql57b:
$ scp mysql56a-fullbackup.sql [email protected]:~
$ scp mysql56a-fullbackup.sql [email protected]:~
Förbereder slavklustret
I denna fas kommer vi att konfigurera slavklustret för att börja replikera från den gamla mastern, mysql56a utan GTID.
1) Stoppa replikeringen mellan mysql57a och mysql57b, ta bort alla slavrelaterade autentiseringsuppgifter som konfigurerats av ClusterControl och inaktivera skrivskyddat på mysql57b:
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
mysql> SET GLOBAL super_read_only = 0;
mysql> SET GLOBAL read_only = 0;
2) Inaktivera GTID på mysql57a:
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) Inaktivera GTID på mysql57b:
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) Återställ mysqldump-säkerhetskopian på mysql57a:
$ mysql -uroot -p < mysql56a-fullbackup.sql
5) Återställ mysqldump-säkerhetskopian på mysql57b:
$ mysql -uroot -p < mysql56a-fullbackup.sql
6) Kör MySQL-uppgraderingsskriptet på mysql57a (för att kontrollera och uppdatera alla tabeller till den aktuella versionen):
$ mysql_upgrade -uroot -p
7) Kör MySQL-uppgraderingsskriptet på mysql57b (för att kontrollera och uppdatera alla tabeller till den aktuella versionen):
$ mysql_upgrade -uroot -p
Båda servrarna på slavklustret är nu iscensatta med dataögonblicksbilden från den gamla mastern, mysql56a, och är nu redo att replikera.
Ställa in replikering för slavklustret
1) Återställ binära loggar med RESET MASTER på mysql57a, så att vi inte behöver specificera den binära filen och loggpositionen senare på mysql57b. Dessutom tar vi bort alla befintliga GTID-referenser som konfigurerades tidigare:
mysql> RESET MASTER;
mysql> SET @@global.gtid_purged='';
2) På mysql57a, hämta binlogfilen och positionen från dumpfilen, mysql56a-fullbackup.sql:
$ head -100 mysql56a-fullbackup.sql | grep LOG_POS
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000007', MASTER_LOG_POS=4677987;
3) Starta replikeringsslaven från den gamla mastern, mysql56a till den nya mastern mysql57a, genom att ange de korrekta MASTER_LOG_FILE- och MASTER_LOG_POS-värdena hämtade i föregående steg. På 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
Se till att du ser följande rader:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Du måste förmodligen vänta tills mysql57a kommer ikapp mysql56a genom att övervaka "Seconds_Behind_Master" och se till att den blir 0.
4) Vid det här laget replikerar mysql57a data från mysql56a, vilket innebär att alla användare som skapats av ClusterControl nu saknas från servern (eftersom mysql57a nu följer data på mysql56a). ClusterControl kommer att ha problem med att ansluta till mysql57a och det kommer att visas som "ner". Det betyder i princip att ClusterControl inte kan ansluta till MySQL-servrarna eftersom anslagen saknas. De saknade användarna är:
- [email protected]
- [email protected]'{alla noder i ett visst kluster}'
- [email protected]'{ClusterControl host}'
Alla referenser lagras säkert i ClusterControl och själva databasservern. Du måste ha root-åtkomst för att kunna hämta autentiseringsuppgifterna från de relevanta filerna.
Låt oss nu återskapa de saknade användarna på den nya mastern, mysql57a:
a) Skapa backup-användare (lösenordet hämtat från /etc/mysql/secrets-backup.cnf på 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) Skapa replikeringsanvändare för alla DB-värdar (lösenordet hämtat från variabeln repl_password inuti /etc/cmon.d/cmon_X.cnf på ClusterControl-servern, där X är kluster-ID:t för slavklustret):
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) Skapa två cmon-databasanvändare (en för IP-adress och en för värdnamn) för ClusterControl-användning (lösenordet hämtat från mysql_password-variabeln inuti /etc/cmon.d/cmon_X.cnf på ClusterControl-servern, där X är kluster-ID:t för slaven kluster):
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) Vid det här laget bör mysql57a visas grönt i ClusterControl. Nu kan vi skapa en replikeringslänk från mysql57a till mysql57b. På 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
**Vi behöver inte ange MASTER_LOG_FILE och MASTER_LOG_POS eftersom det alltid börjar med en fast startposition efter RESET MASTER i steg #1.
Se till att du ser följande rader:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Övervaka replikeringsstatusen och se till att mysql57b hänger med mysql57a och mysql57a hänger med mysql56a. Du kan behöva aktivera skrivskyddat på mysql57b (och/eller mysql57a) efter det, för att skydda mot oavsiktliga skrivningar.
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Från ClusterControl UI ser du det aktuella läget under avsnittet Översikt:
Vid denna punkt replikerar den nya mastern mysql57a, 192.168.10.31 från den gamla fristående värden mysql56a, 192.168.10.22, medan den nya slaven mysql57b (skrivskyddad) replikerar från mysql57a, 192.168.10.31. Alla noder synkroniseras med replikeringsfördröjningen 0.
Alternativt kan du kommentera följande rader i MySQL-konfigurationsfiler under avsnittet [mysqld]:
#gtid_mode=ON
#enforce_gtid_consistency=1
Aktivera GTID på slavklustret
Observera att för MySQL 5.6 och senare stöder ClusterControl inte implementeringen av icke-GTID på vissa av dess hanteringsfunktioner längre, som Rebuild Replication Slave och Change Replication Master. Så under bryttiden (när du pekar applikationer till det nya klustret) från den fristående MySQL-servern (mysql56a), rekommenderas det att aktivera GTID tillbaka på mysql57a och mysql57b med följande steg:
1) Se till att stänga av ClusterControls automatiska återställningsfunktion:
2) Under det avbrutna underhållsfönstret måste vi sluta replikera från den gamla mastern, mysql56a, ta bort all slavkonfiguration på mysql57a och aktivera tillbaka GTID. På mysql57a, kör följande kommandon i rätt ordning:
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';
Vid denna tidpunkt är det praktiskt taget säkert för din applikation att börja skriva till den nya mastern, mysql57a. Den gamla fristående MySQL är nu utanför replikeringskedjan och kan stängas av.
3) Upprepa samma steg för mysql57b. Kom ihåg att följa stegen i rätt ordning:
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) Återställ sedan master på den nya mastern, mysql57a:
mysql> RESET MASTER;
3) Sedan på den nya slaven, mysql57b ställ in replikeringslänken med GTID till mysql57a:
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
Se till att fälten Retrieved_Gtid_Set och Executed_Gtid_Set har sitt GTID-värde.
4) Vid det här laget har vi återställt replikeringskonfigurationen som den tidigare konfigurerats av ClusterControl under klusterdistributionen. Vi kan sedan aktivera skrivskyddat på den nya slaven, mysql57b för att skydda den mot oavsiktliga skrivningar:
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Äntligen, återaktivera ClusterControl automatisk återställning för klustret, genom att växla strömikonerna till gröna. Du kan sedan avveckla den gamla mästaren, mysql56a. Vi har precis slutfört vår onlinemigrering från MySQL 5.6 till MySQL 5.7 med mycket minimal stilleståndstid. Liknande steg bör också fungera för migrering till MySQL 8.0.