Nesta postagem de blog, veremos como realizar a migração online da configuração autônoma do MySQL 5.6 para um novo conjunto de replicação em execução no MySQL 5.7, implantado e gerenciado pelo ClusterControl.
O plano é configurar um link de replicação do novo cluster em execução no MySQL 5.7 para o mestre em execução no MySQL 5.6 (fora da provisão do ClusterControl), que não usa GTID. O MySQL não suporta a mistura de GTID e não-GTID em uma cadeia de replicação. Portanto, precisamos fazer alguns truques para alternar entre os modos não GTID e GTID durante a migração.
Nossa arquitetura e plano de migração podem ser ilustrados abaixo:
A configuração consiste em 4 servidores, com a seguinte representação:
- mysql56a - Antigo mestre - Oracle MySQL 5.6 sem GTID
- Cluster escravo:
- mysql57a - Novo mestre - Oracle MySQL 5.7 com GTID
- mysql57b - Novo escravo - Oracle MySQL 5.7 com GTID
- cc - ClusterControl Server - Servidor de implantação/gerenciamento/monitoramento para os nós do banco de dados.
Todos os hosts MySQL 5.7 estão rodando no Debian 10 (Buster), enquanto o MySQL 5.6 está rodando no Debian 9 (Stretch).
Implantando o cluster escravo
Em primeiro lugar, vamos preparar o cluster escravo antes de configurar um link de replicação do antigo mestre. A configuração final do cluster escravo será executada no MySQL 5.7, com o GTID habilitado. Instale o ClusterControl no servidor ClusterControl (cc):
$ wget https://severalnines.com/downloads/install-cc
$ chmod 755 install-cc
$ ./install-cc
Siga as instruções até que a instalação seja concluída. Em seguida, configure o SSH sem senha do ClusterControl para mysql57a e 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
Em seguida, faça login na interface do usuário do ClusterControl, preencha o formulário inicial e vá para a seção ClusterControl -> Deploy -> MySQL Replication e preencha o seguinte:
Em seguida, clique em Continuar e escolha Oracle como fornecedor e 5.7 como fornecedor versão. Em seguida, prossiga para a seção de topologia e configure-a conforme abaixo:
Aguarde até que a implantação seja concluída e você verá o novo cluster conforme abaixo:
Nosso cluster escravo em execução no MySQL 5.7 com GTID está pronto.
Preparando o Velho Mestre
O mestre atual que queremos replicar é um MySQL 5.6 autônomo (log binário habilitado, server-id configurado, sem GTID) e está servindo bancos de dados de produção. Portanto, o tempo de inatividade não é uma opção para essa migração. Por outro lado, o ClusterControl configura o novo MySQL 5.7 com habilitado para GTID, o que significa que precisamos desativar a funcionalidade GTID dentro do cluster escravo para poder replicar corretamente desse mestre autônomo.
As linhas a seguir mostram nossa configuração atual relacionada à replicação para o mestre /etc/mysql/mysql.conf.d/mysqld.cnf sob a diretiva [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
Verifique se o servidor MySQL está produzindo log binário, sem 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)
Para não-GTID, o Executed_Gtid_Set deve estar vazio. Observe que nosso novo cluster de replicação MySQL 5.7 implantado pelo ClusterControl está configurado com o GTID habilitado.
1) Crie um usuário de replicação para ser usado pelo mysql57a:
mysql> CREATE USER 'slave'@'192.168.10.31' IDENTIFIED BY 'slavepassword';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@192.168.10.31';
2) Desative a recuperação automática do ClusterControl. Em ClusterControl UI -> escolha o cluster -> certifique-se de que o cluster e o nó de recuperação automática estejam desligados (ícones de energia vermelhos), conforme mostrado na captura de tela abaixo:
Não queremos que o ClusterControl recupere o nó durante esta configuração de replicação.
3) Agora precisamos criar um backup completo do mysqldump, pois esta será uma atualização de versão principal. Outras ferramentas de backup sem bloqueio, como Percona Xtrabackup ou MySQL Enterprise Backup, não suportam a restauração para uma versão principal diferente. Também precisamos preservar o arquivo de log binário atual e a posição usando o sinalizador --master-data:
$ mysqldump -u root -p --single-transaction --master-data=2 --all-databases > mysql56a-fullbackup.sql
Observe que o comando acima não bloqueará nenhuma tabela InnoDB por causa de --single-transaction. Portanto, se você possui tabelas MyISAM, as tabelas serão bloqueadas durante o período de backups para manter a consistência.
4) Copie o backup de mysql56a para mysql57a e mysql57b:
$ scp mysql56a-fullbackup.sql [email protected]:~
$ scp mysql56a-fullbackup.sql [email protected]:~
Preparando o cluster escravo
Nesta fase, vamos configurar o cluster escravo para iniciar a replicação do antigo mestre, mysql56a sem GTID.
1) Pare a replicação entre mysql57a e mysql57b, remova todas as credenciais relacionadas ao slave configuradas pelo ClusterControl e desabilite somente leitura no mysql57b:
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
mysql> SET GLOBAL super_read_only = 0;
mysql> SET GLOBAL read_only = 0;
2) Desabilite o GTID no 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) Desabilite o GTID no 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) Restaure o backup do mysqldump no mysql57a:
$ mysql -uroot -p < mysql56a-fullbackup.sql
5) Restaure o backup do mysqldump no mysql57b:
$ mysql -uroot -p < mysql56a-fullbackup.sql
6) Execute o script de atualização do MySQL no mysql57a (para verificar e atualizar todas as tabelas para a versão atual):
$ mysql_upgrade -uroot -p
7) Execute o script de atualização do MySQL no mysql57b (para verificar e atualizar todas as tabelas para a versão atual):
$ mysql_upgrade -uroot -p
Ambos os servidores no cluster escravo agora estão preparados com o instantâneo de dados do antigo mestre, mysql56a, e agora estão prontos para replicar.
Configurando a replicação para o cluster escravo
1) Redefina os logs binários usando RESET MASTER no mysql57a, para que não precisemos especificar o arquivo binário e o posicionamento do log posteriormente no mysql57b. Além disso, removemos todas as referências GTID existentes que foram configuradas antes:
mysql> RESET MASTER;
mysql> SET @@global.gtid_purged='';
2) No mysql57a, recupere o arquivo binlog e a posição do arquivo dump, mysql56a-fullbackup.sql:
$ head -100 mysql56a-fullbackup.sql | grep LOG_POS
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000007', MASTER_LOG_POS=4677987;
3) Inicie o slave de replicação do mestre antigo, mysql56a para o novo mestre mysql57a, especificando os valores MASTER_LOG_FILE e MASTER_LOG_POS corretos recuperados na etapa anterior. No 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
Certifique-se de ver as seguintes linhas:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Você provavelmente precisa esperar até que o mysql57a alcance o mysql56a monitorando o "Seconds_Behind_Master" e certificando-se de que ele vira 0.
4) Neste ponto, mysql57a está replicando dados de mysql56a, o que significa que todos os usuários criados pelo ClusterControl agora estão ausentes do servidor (porque mysql57a agora está seguindo os dados em mysql56a). O ClusterControl terá um problema para se conectar ao mysql57a e aparecerá como "inativo". Basicamente significa que o ClusterControl não consegue se conectar aos servidores MySQL porque as concessões estão faltando. Os usuários ausentes são:
- [email protected]
- [email protected]'{todos os nós em um cluster específico}'
- [email protected]'{ClusterControl host}'
Todas as credenciais são armazenadas de forma segura no ClusterControl e no próprio servidor de banco de dados. Você precisa ter acesso root para recuperar as credenciais dos arquivos relevantes.
Agora, vamos recriar os usuários ausentes no novo mestre, mysql57a:
a) Crie um usuário de backup (senha retirada de /etc/mysql/secrets-backup.cnf no 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) Crie usuários de replicação, para todos os hosts de banco de dados (senha obtida da variável repl_password dentro de /etc/cmon.d/cmon_X.cnf no servidor ClusterControl, onde X é o ID do cluster escravo):
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) Crie dois usuários do banco de dados cmon (um para o endereço IP e outro para o nome do host) para uso do ClusterControl (senha obtida da variável mysql_password dentro de /etc/cmon.d/cmon_X.cnf no servidor ClusterControl, onde X é o ID do cluster do escravo cacho):
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) Neste ponto, mysql57a deve aparecer verde no ClusterControl. Agora, podemos configurar um link de replicação de mysql57a para mysql57b. No 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
**Não precisamos especificar MASTER_LOG_FILE e MASTER_LOG_POS porque sempre começará com uma posição inicial fixa após RESET MASTER na etapa #1.
Certifique-se de ver as seguintes linhas:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Monitore o status da replicação e certifique-se de que o mysql57b acompanha o mysql57a e o mysql57a acompanha o mysql56a. Você pode precisar habilitar somente leitura no mysql57b (e/ou mysql57a) depois disso, para proteger contra escritas acidentais.
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Na IU do ClusterControl, você vê o estado atual na seção Visão geral:
Neste ponto, o novo mestre mysql57a, 192.168.10.31 está replicando de o antigo host autônomo mysql56a, 192.168.10.22, enquanto o novo escravo mysql57b (somente leitura) está replicando do mysql57a, 192.168.10.31. Todos os nós são sincronizados com o atraso de replicação 0.
Alternativamente, você pode comentar as seguintes linhas dentro dos arquivos de configuração do MySQL na seção [mysqld]:
#gtid_mode=ON
#enforce_gtid_consistency=1
Habilitando GTID no cluster escravo
Observe que para o MySQL 5.6 e posterior, o ClusterControl não suporta mais a implementação não-GTID em alguns de seus recursos de gerenciamento, como Rebuild Replication Slave e Change Replication Master. Portanto, durante o tempo limite (quando você aponta aplicativos para o novo cluster) do servidor MySQL autônomo (mysql56a), é recomendado habilitar o GTID de volta no mysql57a e mysql57b com as seguintes etapas:
1) Certifique-se de desativar o recurso de recuperação automática do ClusterControl:
2) Durante a janela de manutenção de corte, temos que parar de replicar do antigo mestre, mysql56a, remova toda a configuração do escravo no mysql57a e habilite novamente o GTID. No mysql57a, execute os seguintes comandos na ordem correta:
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';
Neste ponto, é praticamente seguro para seu aplicativo começar a gravar no novo mestre, mysql57a. O antigo MySQL autônomo está fora da cadeia de replicação e pode ser encerrado.
3) Repita os mesmos passos para mysql57b. Lembre-se de seguir os passos na ordem correta:
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) Em seguida, redefina o master no novo master, mysql57a:
mysql> RESET MASTER;
3) Então no novo slave, mysql57b configura o link de replicação usando GTID para 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
Verifique se os campos Retrieved_Gtid_Set e Executed_Gtid_Set têm seu valor GTID.
4) Neste ponto, restauramos a configuração de replicação conforme configurada anteriormente pelo ClusterControl durante o estágio de implantação do cluster. Podemos então habilitar somente leitura no novo escravo, mysql57b para protegê-lo contra escritas acidentais:
mysql> SET GLOBAL super_read_only = 1;
mysql> SET GLOBAL read_only = 1;
Finalmente, reative a recuperação automática do ClusterControl para o cluster, alternando os ícones de energia para verde. Você pode então descomissionar o antigo mestre, mysql56a. Acabamos de concluir nossa migração online do MySQL 5.6 para o MySQL 5.7 com tempo de inatividade mínimo. As etapas semelhantes também devem funcionar para a migração para o MySQL 8.0.