TL;DR — Resumo Rápido

Guia completo de replicacao MySQL master-slave para alta disponibilidade: binary logs, configuracao de slaves, monitoramento de lag, failover e ProxySQL.

A replicacao do MySQL permite que um servidor (o master) transmita cada alteracao de dados para um ou mais servidores replica (slaves) em tempo quase real. O resultado e uma arquitetura de alta disponibilidade onde o trafego de leitura e distribuido entre varios nos, backups podem ser feitos a partir de um slave sem afetar o master, e um slave pode ser promovido a master em minutos se o servidor primario falhar. Este guia cobre a configuracao completa de replicacao master-slave no MySQL 8.0: desde a configuracao de binary logs e sincronizacao inicial de dados ate monitoramento de lag, recuperacao de replicacao quebrada, procedimentos de failover e separacao de leitura/escrita com ProxySQL.

Arquitetura de Replicacao

A replicacao do MySQL funciona atraves de tres componentes trabalhando em conjunto:

  • Binary log (binlog) — o master registra cada transacao confirmada em um arquivo de log sequencial. Existem tres formatos: STATEMENT (registra o texto SQL), ROW (registra os valores antes/depois das linhas modificadas) e MIXED (usa STATEMENT por padrao e muda para ROW para funcoes nao deterministas). Sempre use ROW em producao.
  • IO thread — uma thread no slave se conecta ao master, le os novos eventos do binary log e os escreve no relay log local.
  • SQL thread — uma segunda thread no slave le o relay log e reproduz os eventos no banco de dados local, mantendo os dados sincronizados.

Modos de Replicacao

ModoComo FuncionaQuando Usar
Assincrono (padrao)O master nao aguarda ACK do slaveHA geral, escalonamento de leituras
Semi-sincronoMaster aguarda ao menos um slave gravar o relay logDados financeiros, menor risco de perda
Group ReplicationMulti-master com protocolo de consenso (Paxos)Ativo-ativo, failover automatico

Pre-requisitos

  • Dois servidores Linux com MySQL 8.0 ou 8.4 (Ubuntu 22.04+ ou RHEL 9+)
  • Acesso root ou sudo em ambos os servidores
  • Conectividade de rede entre master e slave (porta 3306 aberta)
  • server-id do master e do slave devem ser inteiros unicos em toda a topologia

Passo 1: Configurar o Servidor Master

Edite a configuracao do MySQL no master:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Adicione ou modifique essas configuracoes na secao [mysqld]:

[mysqld]
# ID unico para este servidor — deve ser diferente em cada no
server-id = 1

# Habilita o binary log — obrigatorio para replicacao
log-bin = /var/log/mysql/mysql-bin
binlog-format = ROW

# Manter 7 dias de binary logs
expire_logs_days = 7

# Sincroniza o binlog para disco a cada commit — evita perda de dados
sync_binlog = 1

# Replicacao baseada em GTID (recomendada para MySQL 8.0+)
gtid_mode = ON
enforce_gtid_consistency = ON

Aplique a configuracao:

sudo systemctl restart mysql

Verifique que o binary log esta ativo:

SHOW VARIABLES LIKE 'log_bin';
-- log_bin | ON

SHOW MASTER STATUS\G
-- File: mysql-bin.000003
-- Position: 1573

Passo 2: Criar o Usuario de Replicacao

No master, crie um usuario dedicado com apenas as permissoes necessarias para replicacao:

CREATE USER 'repl'@'192.168.1.102' IDENTIFIED BY 'ReplStr0ng!Pass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.102';
FLUSH PRIVILEGES;

Substitua 192.168.1.102 pelo IP real do slave. Nunca use % (qualquer host) para usuarios de replicacao — restrinja por IP por seguranca.

Passo 3: Tirar um Snapshot Consistente

Voce precisa de um snapshot consistente em um ponto no tempo do master para inicializar o slave. O flag --master-data registra automaticamente a posicao do binary log dentro do arquivo de dump.

# Opcao A: mysqldump (adequado para bancos de dados abaixo de ~50 GB)
mysqldump -u root -p \
  --all-databases \
  --master-data=2 \
  --single-transaction \
  --flush-logs \
  --routines \
  --triggers \
  > /tmp/master_dump.sql

# Opcao B: Percona XtraBackup (recomendado para bancos grandes, sem bloqueio de tabelas)
xtrabackup --backup --user=root --password=minhasenha \
  --target-dir=/tmp/xtrabackup/
xtrabackup --prepare --target-dir=/tmp/xtrabackup/

Transfira o dump para o slave:

scp /tmp/master_dump.sql usuario@192.168.1.102:/tmp/

Passo 4: Configurar o Servidor Slave

No slave, edite mysqld.cnf:

[mysqld]
# Deve ser diferente do master e de todos os outros slaves
server-id = 2

# Localizacao do relay log
relay-log = /var/log/mysql/mysql-relay-bin

# Evita escritas acidentais no slave
read_only = 1
super_read_only = 1

# Necessario se este slave tambem sera um master (replicacao em cadeia)
log_slave_updates = 1

# Coincide com as configuracoes GTID do master
gtid_mode = ON
enforce_gtid_consistency = ON
sudo systemctl restart mysql

Passo 5: Importar o Snapshot e Iniciar a Replicacao

Restaure o dump do master no slave:

mysql -u root -p < /tmp/master_dump.sql

Configure o slave para se conectar ao master. Com modo GTID (recomendado):

CHANGE MASTER TO
  MASTER_HOST          = '192.168.1.101',
  MASTER_USER          = 'repl',
  MASTER_PASSWORD      = 'ReplStr0ng!Pass',
  MASTER_AUTO_POSITION = 1;

Sem GTID (baseado em posicao tradicional), encontre a posicao no comentario do dump:

grep "MASTER_LOG_FILE\|MASTER_LOG_POS" /tmp/master_dump.sql | head -5
# -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=1573;
CHANGE MASTER TO
  MASTER_HOST     = '192.168.1.101',
  MASTER_USER     = 'repl',
  MASTER_PASSWORD = 'ReplStr0ng!Pass',
  MASTER_LOG_FILE = 'mysql-bin.000003',
  MASTER_LOG_POS  = 1573;

Inicie a replicacao:

START SLAVE;

Passo 6: Monitorar a Saude da Replicacao

SHOW SLAVE STATUS\G

Campos chave a verificar:

Slave_IO_Running: Yes          -- thread IO conectada e em execucao
Slave_SQL_Running: Yes         -- thread SQL reproduzindo eventos
Seconds_Behind_Master: 0       -- slave completamente atualizado
Last_IO_Error: (vazio)         -- sem erros de conexao
Last_SQL_Error: (vazio)        -- sem erros de reproducao

Para monitoramento continuo via performance_schema (MySQL 8.0+):

SELECT
  CHANNEL_NAME,
  SERVICE_STATE,
  LAST_ERROR_MESSAGE,
  LAST_HEARTBEAT_TIMESTAMP
FROM performance_schema.replication_connection_status;

Tratamento do Lag de Replicacao

O lag de replicacao (Seconds_Behind_Master crescendo) e comum sob cargas de escrita intensas:

CausaSolucao
Thread SQL single-threadedHabilite workers de replicacao paralela
Consultas lentas no slaveIdentifique com SHOW PROCESSLIST; otimize
Gargalo de I/O no slaveMova os relay logs para armazenamento mais rapido
Transacoes em massaDivida em lotes menores no master
Latencia de redeCo-localize master e slaves no mesmo datacenter

Habilitar replicacao paralela (MySQL 8.0):

STOP SLAVE SQL_THREAD;
SET GLOBAL slave_parallel_workers = 4;
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
START SLAVE SQL_THREAD;

Corrigindo Replicacao Quebrada

Quando Slave_SQL_Running: No aparece em SHOW SLAVE STATUS:

Pular uma Unica Transacao com Erro

STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
SHOW SLAVE STATUS\G

Pular por GTID (Mais Seguro com Modo GTID)

STOP SLAVE;
-- Substitua pelo GTID da mensagem Last_SQL_Error
SET GTID_NEXT = 'a1b2c3d4-1111-2222-3333-444444444444:1234';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START SLAVE;

Ressincronizacao Completa a partir do Master

STOP SLAVE;
RESET SLAVE ALL;
-- Tire o snapshot novamente a partir do Passo 3 e reconfigure

Failover: Promovendo um Slave a Master

Quando o master falha e voce precisa promover um slave:

-- No slave a ser promovido:
SHOW SLAVE STATUS\G
-- Seconds_Behind_Master: 0

STOP SLAVE;
RESET SLAVE ALL;

-- Desabilita modo somente leitura — este servidor e agora o master
SET GLOBAL read_only = 0;
SET GLOBAL super_read_only = 0;

Atualize as strings de conexao da aplicacao para o novo IP do master e reconfigure os slaves restantes:

-- Nos slaves restantes:
STOP SLAVE;
CHANGE MASTER TO
  MASTER_HOST          = '192.168.1.102',
  MASTER_AUTO_POSITION = 1;
START SLAVE;

Passo 7: ProxySQL para Separacao Leitura/Escrita

O ProxySQL fica entre a aplicacao e o MySQL, roteando escritas para o master e leituras para os slaves de forma transparente.

# Instalar ProxySQL (Ubuntu)
wget -O - 'https://repo.proxysql.com/ProxySQL/repo_pub_key' | sudo apt-key add -
echo "deb https://repo.proxysql.com/ProxySQL/proxysql-2.x/$(lsb_release -sc)/ ./" \
  | sudo tee /etc/apt/sources.list.d/proxysql.list
sudo apt update && sudo apt install proxysql
sudo systemctl enable --now proxysql

Configure atraves da interface admin do ProxySQL (porta 6032):

-- Adicionar servidores: hostgroup 0 = escrita (master), hostgroup 1 = leitura (slave)
INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES
  (0, '192.168.1.101', 3306),
  (1, '192.168.1.102', 3306);

-- Adicionar usuario da aplicacao
INSERT INTO mysql_users (username, password, default_hostgroup) VALUES
  ('appuser', 'AppPass123!', 0);

-- Rotear consultas SELECT para o hostgroup de leitura
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES
  (1, 1, '^SELECT.*', 1, 1);

-- Aplicar e persistir mudancas
LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL USERS TO RUNTIME;   SAVE MYSQL USERS TO DISK;
LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;

A aplicacao se conecta ao ProxySQL na porta 6033 e todo o roteamento e gerenciado de forma transparente.

Comparacao: Replicacao MySQL vs Alternativas

SolucaoArquiteturaFailoverEscalonamento de EscritaComplexidade
Replicacao MySQLMaster + slavesManual ou MHANao (master unico)Baixa
MySQL Group ReplicationMulti-master PaxosAutomaticoLimitadoMedia
Galera Cluster (MariaDB)Multi-master sincronoAutomaticoSimMedia
VitessMySQL com shardingAutomaticoSim (sharding)Alta
PlanetScaleVitess gerenciadoGerenciadoSimBaixa (gerenciado)
PostgreSQL StreamingPrimario + standbysPatroni/manualNaoBaixa-Media

Pontos de Atencao

  • server-id deve ser globalmente unico em todos os nos — dois nos com o mesmo ID corrompem silenciosamente a replicacao
  • read_only=1 nao bloqueia usuarios SUPER — use super_read_only=1 para bloquear completamente o slave
  • Transacoes grandes bloqueiam a thread IO — use pt-online-schema-change para operacoes DDL grandes
  • Diferenca de fuso horario causa erros de replicacao — defina default-time-zone='+00:00' em todos os nos

Resumo

  • A replicacao MySQL usa binary logs, threads IO e threads SQL para manter os slaves sincronizados
  • Use binlog-format=ROW, sync_binlog=1 e modo GTID (gtid_mode=ON) em producao
  • Monitore Slave_IO_Running, Slave_SQL_Running e Seconds_Behind_Master continuamente
  • Habilite workers de replicacao paralela para reduzir o lag sob cargas de escrita intensas
  • Use RESET SLAVE ALL para uma reconfiguracao limpa em vez de tentar corrigir um estado quebrado
  • O ProxySQL roteia transparentemente leituras para os slaves e escritas para o master

Artigos Relacionados