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

Modo Como Funciona Quando Usar
Assincrono (padrao) O master nao aguarda ACK do slave HA geral, escalonamento de leituras
Semi-sincrono Master aguarda ao menos um slave gravar o relay log Dados financeiros, menor risco de perda
Group Replication Multi-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:

Causa Solucao
Thread SQL single-threaded Habilite workers de replicacao paralela
Consultas lentas no slave Identifique com SHOW PROCESSLIST; otimize
Gargalo de I/O no slave Mova os relay logs para armazenamento mais rapido
Transacoes em massa Divida em lotes menores no master
Latencia de rede Co-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

Solucao Arquitetura Failover Escalonamento de Escrita Complexidade
Replicacao MySQL Master + slaves Manual ou MHA Nao (master unico) Baixa
MySQL Group Replication Multi-master Paxos Automatico Limitado Media
Galera Cluster (MariaDB) Multi-master sincrono Automatico Sim Media
Vitess MySQL com sharding Automatico Sim (sharding) Alta
PlanetScale Vitess gerenciado Gerenciado Sim Baixa (gerenciado)
PostgreSQL Streaming Primario + standbys Patroni/manual Nao Baixa-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