MySQL Replication com GTID na prática: simulando failover e recuperação do ambiente
Em ambientes críticos, indisponibilidade de banco de dados não é uma opção.
Por isso, uma arquitetura com replicação e failover é essencial para garantir continuidade do serviço.
Neste post vamos fazer um laboratório completo:
- configurar replicação com GTID
- criar um master e uma réplica
- simular queda do master
- promover automaticamente a réplica
- inserir novos dados
- trazer o antigo master de volta como réplica
- validar que tudo sincronizou corretamente
Tudo isso com comandos reais e validações práticas.
Arquitetura do laboratório
Ambiente utilizado:
Master original
mysql01
IP: 10.0.0.73
server-id: 1Replica
mysql02
IP: 10.0.0.147
server-id: 2Configuração inicial do GTID
Em ambos os servidores configuramos no my.cnf.
server-id=1 (ou 2 na replica)
log_bin=binlog
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ONReiniciamos o MySQL:
systemctl restart mysqldValidação:
SELECT
@@hostname,
@@server_id,
@@gtid_mode,
@@enforce_gtid_consistency,
@@log_bin,
@@binlog_format,
@@log_slave_updates;
Resultado esperado:
*************************** 1. row ***************************
@@hostname: mysql02.localdomain
@@server_id: 2
@@gtid_mode: ON
@@enforce_gtid_consistency: ON
@@log_bin: 1
@@binlog_format: ROW
@@log_slave_updates: 1
–Master
Criando usuário de replicação
No mysql01 (master):
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'Senha123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;Criando banco de teste
CREATE DATABASE lab_failover;
USE lab_failover;
CREATE TABLE pedidos (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
cliente VARCHAR(100),
valor DECIMAL(10,2),
data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Inserindo dados iniciais:
INSERT INTO pedidos (cliente, valor)
VALUES
('CLIENTE_1',100),
('CLIENTE_2',200),
('CLIENTE_3',300);
Configurando a réplica com GTIDNa Replica
Configurar a replicação
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='10.0.0.73',
SOURCE_USER='repl',
SOURCE_PASSWORD='Senha123',
SOURCE_AUTO_POSITION=1;
START REPLICA;
Para validar a replicação execute o comando abaixo.
SHOW REPLICA STATUS\G
Campos importantes:
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Seconds_Behind_Source: 0
Auto_Position: 1Criando script de monitoramento e promoção automática
Criamos um script simples que verifica se o master está disponível, caso não esteja, promove a réplica automaticamente.
mysql_failover.sh
Conteúdo:
#!/bin/bash
MASTER="10.0.0.73"
REPLICA="127.0.0.1"
MYSQL_USER="monitor"
MYSQL_PASS="Senha123"
LOG="/var/log/mysql_failover.log"
DATA=$(date "+%Y-%m-%d %H:%M:%S")
mysql -h $MASTER -u $MYSQL_USER -p$MYSQL_PASS -e "SELECT 1;" >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$DATA - Master $MASTER indisponível. Iniciando promoção da réplica." >> $LOG
mysql -h $REPLICA -u $MYSQL_USER -p$MYSQL_PASS -e "
STOP REPLICA;
RESET REPLICA ALL;
SET GLOBAL read_only = OFF;
"
echo "$DATA - Réplica promovida a MASTER com sucesso." >> $LOG
else
echo "$DATA - Master OK." >> $LOG
fi
No master crie o usuario que utilizara o script.
CREATE USER 'monitor'@'%' IDENTIFIED BY 'Senha123';
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'monitor'@'%';
GRANT REPLICATION_SLAVE_ADMIN ON *.* TO 'monitor'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'monitor'@'%';
GRANT RELOAD ON *.* TO 'monitor'@'%';
FLUSH PRIVILEGES;Agendando execução automática
Adicionamos no cron:
crontab -e
* * * * * /home/mysql_failover.sh
O script roda a cada 1 minuto.
Simulando queda do master
systemctl stop mysqld
O log registrou:
2026-03-14 12:34:01 - Master 10.0.0.73 indisponível. Iniciando promoção da réplica.
2026-03-14 12:34:01 - Réplica promovida a MASTER com sucesso.
Validando promoção da réplica
No mysql02:
SHOW REPLICA STATUS;Resultado:
Empty set
Isso indica que ele não está mais replicando.
Confirmando escrita liberada:
SELECT @@read_only;Resultado:
0
Verificando binlog ativo:
SHOW MASTER STATUS;
*************************** 1. row ***************************
File: binlog.000004
Position: 5185
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 00c7b540-1fa7-11f1-ab7f-080027897cb8:1-18,
b5e7f644-1fad-11f1-a884-0800273938b6:1-2
1 row in set (0,00 sec)
Agora o mysql02 é o novo master.
Inserindo novos dados após o failover
No novo master:
USE lab_failover;
INSERT INTO pedidos (cliente, valor)
VALUES
('DEPOIS_FAILOVER_1',500),
('DEPOIS_FAILOVER_2',750);Subindo novamente o antigo master
No mysql01:
systemctl start mysqldConfigurando replicação para o novo master:
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='10.0.0.147',
SOURCE_USER='repl',
SOURCE_PASSWORD='Senha123',
SOURCE_AUTO_POSITION=1;
Iniciar replicação:
START REPLICA;
Validando sincronização
No mysql01:
SHOW REPLICA STATUS\G
Resultado esperado:
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Seconds_Behind_Source: 0
Source_Host: 10.0.0.147Validando dados replicados
No mysql01:
USE lab_failover;
SELECT * FROM pedidos ORDER BY id;Os registros inseridos após o failover também aparecerão:
+----+-------------------+--------+---------------------+
| id | cliente | valor | data_pedido |
+----+-------------------+--------+---------------------+
| 1 | Joao | 100.00 | 2026-03-14 11:41:23 |
| 2 | Maria | 200.00 | 2026-03-14 11:41:23 |
| 3 | Carlos | 150.00 | 2026-03-14 11:41:23 |
| 4 | Ana | 350.00 | 2026-03-14 12:03:29 |
| 5 | ANTES_DA_QUEDA | 999.00 | 2026-03-14 12:05:58 |
| 6 | DEPOIS_FAILOVER_1 | 500.00 | 2026-03-14 12:39:03 |
| 7 | DEPOIS_FAILOVER_2 | 750.00 | 2026-03-14 12:39:03 |
+----+-------------------+--------+---------------------+
Teste final de sincronismo
No master atual:
INSERT INTO pedidos (cliente, valor)
VALUES ('ULTIMO_TESTE_GTID',999);Na réplica:
SELECT * FROM pedidos
WHERE cliente='ULTIMO_TESTE_GTID'\G;
*************************** 1. row ***************************
id: 8
cliente: ULTIMO_TESTE_GTID
valor: 999.00
data_pedido: 2026-03-14 13:16:32
1 row in set (0,00 sec)
Registro replicado com sucesso.
Considerações finais
Neste laboratório vimos na prática como o GTID simplifica bastante a administração de replicação no MySQL.
Diferente do modelo tradicional baseado em file e position, o GTID permite que a réplica saiba exatamente quais transações já foram executadas, eliminando boa parte da complexidade na hora de reconstruir ou reposicionar uma replicação.
Isso torna operações como:
- recriar réplicas
- promover um novo master
- reintegrar servidores.
muito mais simples e seguras.
No laboratório simulamos um cenário real:
- o master ficou indisponível
- a réplica foi promovida automaticamente
- novos dados foram gravados no novo master
- o antigo master voltou ao ambiente se tornando uma replica e passou a sincronizar transações.
Tudo isso sem precisar lidar manualmente com posições de binlog, justamente graças ao uso de GTID com AUTO_POSITION.
Claro que em um ambiente de produção existem outros componentes importantes que normalmente fazem parte da arquitetura.
Um exemplo clássico é o uso de um VIP (Virtual IP) ou algum mecanismo de balanceamento que redirecione automaticamente as conexões da aplicação para o novo master após um failover.
Dessa forma, quando ocorre a promoção de uma réplica, as aplicações continuam funcionando sem precisar alterar manualmente o endpoint de conexão.
Existem diversas ferramentas que ajudam a automatizar esse tipo de cenário, como:
- MySQL Orchestrator
- ProxySQL
- HAProxy
- Keepalived para gerenciamento de VIP
Mas mesmo em arquiteturas mais simples, entender como o GTID funciona e como a promoção de uma réplica ocorre já é um grande passo para construir ambientes mais resilientes ja que em caso de falha do servidor principal, a réplica pode assumir rapidamente, evitando uma indisponibilidade total do banco de dados.
Importante.
Antes de habilitar o GTID em produção, também é importante validar se as aplicações estão aptas a operar com esse modelo de transação. Para isso, uma boa prática é habilitar inicialmente o parâmetro enforce_gtid_consistency em modo WARN, permitindo identificar nos logs possíveis operações incompatíveis. Dessa forma é possível ajustar o ambiente com segurança antes de ativar o GTID definitivamente.
E o mais importante: testar esses cenários em laboratório antes de precisar deles em produção.
