В тази публикация в блога ще разгледаме как да извършим онлайн миграция от самостоятелна настройка на MySQL 5.6 към нов набор за репликация, работещ на MySQL 5.7, разгърнат и управляван от ClusterControl.
Планът е да се създаде връзка за репликация от новия клъстер, работещ на MySQL 5.7, към главния, работещ на MySQL 5.6 (извън предоставянето на ClusterControl), който не използва GTID. MySQL не поддържа смесване на GTID и не-GTID в една репликационна верига. Така че трябва да направим някои трикове, за да превключваме между режими без GTID и GTID по време на миграцията.
Нашата архитектура и план за миграция могат да бъдат илюстрирани по-долу:
Настройката се състои от 4 сървъра, със следното представяне:
- mysql56a – Стар майстор – Oracle MySQL 5.6 без GTID
- Подчинен клъстер:
- mysql57a - Нов главен код - Oracle MySQL 5.7 с GTID
- mysql57b - Нов подчинен - Oracle MySQL 5.7 с GTID
- cc - ClusterControl Server - Сървър за внедряване/управление/наблюдение за възлите на базата данни.
Всички хостове на MySQL 5.7 работят на Debian 10 (Buster), докато MySQL 5.6 работи на Debian 9 (Stretch).
Разгръщане на подчинения клъстер
Първо, нека подготвим подчинения клъстер, преди да настроим връзка за репликация от стария главен. Окончателната конфигурация на подчинения клъстер ще се изпълнява на MySQL 5.7, с активиран GTID. Инсталирайте ClusterControl на сървъра на ClusterControl (cc):
$ wget https://severalnines.com/downloads/install-cc
$ chmod 755 install-cc
$ ./install-cc
Следвайте инструкциите, докато инсталацията приключи. След това настройте SSH без парола от ClusterControl към mysql57a и 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
След това влезте в потребителския интерфейс на ClusterControl, попълнете първоначалния формуляр и отидете на ClusterControl -> Разгръщане -> MySQL Replication раздел и попълнете следното:
След това щракнете върху Продължи и изберете Oracle като доставчик и 5.7 като доставчик версия. След това преминете към раздела за топология и го конфигурирайте, както следва:
Изчакайте, докато разполагането завърши и трябва да видите новия клъстер, както е посочено по-долу:
Нашият подчинен клъстер, работещ на MySQL 5.7 с GTID, вече е готов.
Подготовка на стария майстор
Текущият главен код, който искаме да репликираме, е самостоятелен MySQL 5.6 (с активиран двоичен дневник, конфигуриран идентификатор на сървъра, без GTID) и обслужва производствени бази данни. Така че престой не е опция за тази миграция. От друга страна, ClusterControl конфигурира новия MySQL 5.7 с активиран GTID, което означава, че трябва да изключим GTID функционалността вътре в подчинения клъстер, за да можем да репликираме правилно от този самостоятелен главен код.
Следните редове показват текущата ни конфигурация, свързана с репликацията, за главния /etc/mysql/mysql.conf.d/mysqld.cnf под [mysqld] директива:
server_id=1
binlog_format=ROW
log_bin=binlog
log_slave_updates=1
relay_log=relay-bin
expire_logs_days=7
sync_binlog=1
Проверете дали MySQL сървърът създава двоичен дневник без 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)
За не-GTID, Executed_Gtid_Set се очаква да е празен. Имайте предвид, че нашият нов клъстер за репликация MySQL 5.7, разгърнат от ClusterControl, е конфигуриран с активиран GTID.
1) Създайте потребител за репликация, който да се използва от mysql57a:
mysql> CREATE USER 'slave'@'192.168.10.31' IDENTIFIED BY 'slavepassword';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@192.168.10.31';
2) Деактивирайте автоматичното възстановяване на ClusterControl. Под ClusterControl UI -> изберете клъстера -> уверете се, че клъстерът и възелът за автоматично възстановяване са изключени (червени икони за захранване), както е показано на екранната снимка по-долу:
Не искаме ClusterControl да възстанови възела по време на тази конфигурация на репликация.
3) Сега трябва да създадем пълен архив на mysqldump, тъй като това ще бъде основна надстройка на версията. Други неблокиращи инструменти за архивиране като Percona Xtrabackup или MySQL Enterprise Backup не поддържат възстановяване до различна основна версия. Също така трябва да запазим текущия двоичен регистрационен файл и позиция, използвайки флага --master-data:
$ mysqldump -u root -p --single-transaction --master-data=2 --all-databases > mysql56a-fullbackup.sql
Обърнете внимание, че горната команда няма да блокира никакви InnoDB таблици поради --single-transaction. Така че, ако имате MyISAM таблици, таблиците ще бъдат блокирани по време на периода на архивиране, за да се поддържа последователност.
4) Копирайте архива от mysql56a в mysql57a и mysql57b:
$ scp mysql56a-fullbackup.sql [email protected]:~
$ scp mysql56a-fullbackup.sql [email protected]:~
Подготовка на подчинения клъстер
На тази фаза ще конфигурираме подчинения клъстер да започне да се репликира от стария главен, mysql56a без GTID.
1) Спрете репликацията между mysql57a и mysql57b, премахнете всички идентификационни данни, свързани с подчинени, конфигурирани от ClusterControl и деактивирайте само за четене на mysql57b:
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
mysql> SET GLOBAL super_read_only = 0;
mysql> SET GLOBAL read_only = 0;
2) Деактивирайте GTID на 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) Деактивирайте GTID на 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) Възстановете архива на mysqldump на mysql57a:
$ mysql -uroot -p < mysql56a-fullbackup.sql
5) Възстановете архива на mysqldump на mysql57b:
$ mysql -uroot -p < mysql56a-fullbackup.sql
6) Изпълнете скрипт за надграждане на MySQL на mysql57a (за да проверите и актуализирате всички таблици до текущата версия):
$ mysql_upgrade -uroot -p
7) Изпълнете скрипт за надграждане на MySQL на mysql57b (за да проверите и актуализирате всички таблици до текущата версия):
$ mysql_upgrade -uroot -p
И двата сървъра в подчинения клъстер вече са подредени със моментната снимка на данните от стария главен, mysql56a, и вече са готови за репликиране.
Настройване на репликация за подчинения клъстер
1) Нулирайте двоичните регистрационни файлове с помощта на RESET MASTER на mysql57a, така че не е нужно да указваме двоичния файл и позиционирането на журнала по-късно в mysql57b. Също така премахваме всички съществуващи препратки към GTID, които са били конфигурирани преди:
mysql> RESET MASTER;
mysql> SET @@global.gtid_purged='';
2) На mysql57a извлечете binlog файла и позицията му от дъмп файла, mysql56a-fullbackup.sql:
$ head -100 mysql56a-fullbackup.sql | grep LOG_POS
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000007', MASTER_LOG_POS=4677987;
3) Стартирайте подчиненото устройство за репликация от стария главен, mysql56a към новия главен mysql57a, като посочите правилните стойности MASTER_LOG_FILE и MASTER_LOG_POS, извлечени в предишната стъпка. На 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
Уверете се, че виждате следните редове:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Вероятно трябва да изчакате, докато mysql57a настигне mysql56a, като наблюдавате „Seconds_Behind_Master“ и се уверите, че става 0.
4) В този момент mysql57a репликира данни от mysql56a, което означава, че всички потребители, създадени от ClusterControl, вече липсват от сървъра (защото mysql57a вече следва данните на mysql56a). ClusterControl ще има проблем да се свърже с mysql57a и ще се появи като "надолу". Това основно означава, че ClusterControl не може да се свърже със сървърите на MySQL, защото липсват разрешения. Липсващите потребители са:
- [email protected]
- [email protected]'{всички възли в един конкретен клъстер}'
- [email protected]'{ClusterControl хост}'
Всички идентификационни данни се съхраняват сигурно в ClusterControl и самия сървър на база данни. Трябва да имате root достъп, за да извлечете идентификационните данни обратно от съответните файлове.
Сега нека пресъздадем липсващите потребители на новия главен файл, mysql57a:
a) Създайте резервен потребител (парола, взета от /etc/mysql/secrets-backup.cnf на 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) Създайте потребители за репликация за всички хостове на DB (паролата, взета от променлива repl_password вътре в /etc/cmon.d/cmon_X.cnf на сървъра ClusterControl, където X е идентификаторът на клъстера на подчинения клъстер):
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';
в) Създайте двама потребители на база данни cmon (един за IP адрес и един за име на хост) за използване на ClusterControl (паролата, взета от променлива mysql_password вътре /etc/cmon.d/cmon_X.cnf на сървъра на ClusterControl, където X е идентификаторът на клъстера на подчинения клъстер):
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) В този момент mysql57a трябва да изглежда зелено в ClusterControl. Сега можем да настроим връзка за репликация от mysql57a към mysql57b. На 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
**Не е необходимо да указваме MASTER_LOG_FILE и MASTER_LOG_POS, защото винаги ще започва с фиксирана начална позиция след НУЛИРАНЕ НА MASTER на стъпка #1.
Уверете се, че виждате следните редове:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Наблюдавайте състоянието на репликация и се уверете, че mysql57b е в крак с mysql57a, а mysql57a е в крак с mysql56a. Може да се наложи да активирате само за четене на mysql57b (и/или mysql57a) след това, за да се предпазите от случайни записи.
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
От потребителския интерфейс на ClusterControl виждате текущото състояние в секцията Общ преглед:
В този момент новият главен mysql57a, 192.168.10.31 се репликира от . старият самостоятелен хост mysql56a, 192.168.10.22, докато новият подчинен mysql57b (само за четене) се репликира от mysql57a, 192.168.10.31. Всички възли се синхронизират със забавяне на репликацията 0.
Като алтернатива можете да коментирате следните редове в конфигурационните файлове на MySQL в секцията [mysqld]:
#gtid_mode=ON
#enforce_gtid_consistency=1
Активиране на GTID в подчинения клъстер
Имайте предвид, че за MySQL 5.6 и по-нови версии, ClusterControl вече не поддържа реализацията без GTID на някои от функциите си за управление, като Rebuild Replication Slave и Change Replication Master. Така че, по време на крайното време (когато насочвате приложения към новия клъстер) от самостоятелния MySQL сървър (mysql56a), се препоръчва да активирате GTID обратно на mysql57a и mysql57b със следните стъпки:
1) Уверете се, че сте изключили функцията за автоматично възстановяване на ClusterControl:
2) По време на прозореца за поддръжка на прекъсване трябва да спрем реплицирането от стария главен, mysql56a, премахнете цялата подчинена конфигурация на mysql57a и активирайте обратно GTID. На mysql57a изпълнете следните команди в правилния ред:
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';
В този момент е практически безопасно приложението ви да започне да пише в новия главен файл, mysql57a. Старият самостоятелен MySQL вече е извън веригата за репликация и може да бъде изключен.
3) Повторете същите стъпки за mysql57b. Не забравяйте да следвате стъпките в правилния ред:
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) След това нулирайте главния на новия главен, mysql57a:
mysql> RESET MASTER;
3) След това на новия подчинен, mysql57b настройте връзката за репликация, използвайки GTID към 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
Уверете се, че виждате полетата Retrieved_Gtid_Set и Executed_Gtid_Set да имат своя GTID стойност.
4) В този момент възстановихме конфигурацията за репликация, както е била конфигурирана преди това от ClusterControl по време на етапа на разгръщане на клъстера. След това можем да активираме само за четене на новия подчинен, mysql57b, за да го защитим от случайни записвания:
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Накрая, активирайте отново автоматичното възстановяване на ClusterControl за клъстера, като превключите иконите за захранване в зелено. След това можете да изведете от експлоатация стария master, mysql56a. Току-що завършихме нашата онлайн миграция от MySQL 5.6 към MySQL 5.7 с много минимално време на престой. Подобни стъпки трябва да работят и при миграция към MySQL 8.0.