Solucionando Rapidamente Falhas Comuns de Replicação do MySQL

Resolva rapidamente falhas comuns de replicação do MySQL com este guia prático. Aprenda a interpretar códigos de erro do `SHOW REPLICA STATUS`, inspecionar logs de erro do MySQL e entender a finalidade dos logs binários. Este artigo fornece etapas acionáveis e melhores práticas para diagnosticar problemas como entradas duplicadas, arquivos binlog ausentes e divergência de dados, ajudando você a manter uma configuração de replicação saudável.

Solucionando Rapidamente Falhas Comuns de Replicação do MySQL

Falhas de replicação do MySQL são mais fáceis de corrigir quando você separa duas perguntas: a réplica consegue buscar eventos da fonte e consegue aplicar os eventos que já buscou? Essas são falhas diferentes. Um problema de rede, log binário ausente, senha incorreta ou permissão de host errada geralmente interrompe a thread de E/S. Uma chave duplicada, linha ausente, incompatibilidade de DDL ou desvio de dados geralmente interrompe a thread SQL.

Comece com a saída de status. No MySQL moderno:

SHOW REPLICA STATUS\G

Em sistemas mais antigos:

SHOW SLAVE STATUS\G

Use o comando que seu servidor suportar. A saída mais recente usa nomes como Replica_IO_Running, Replica_SQL_Running e Seconds_Behind_Source. A saída mais antiga usa Slave_IO_Running, Slave_SQL_Running e Seconds_Behind_Master.

A primeira leitura útil é:

  • Replica_IO_Running: se a réplica está conectada e lendo logs binários da fonte.
  • Replica_SQL_Running: se a réplica está aplicando eventos do log de relay.
  • Last_IO_Errno e Last_IO_Error: por que a busca falhou.
  • Last_SQL_Errno e Last_SQL_Error: por que a aplicação falhou.
  • Relay_Master_Log_File, Exec_Master_Log_Pos ou campos de posição da fonte mais recentes: onde a réplica está no fluxo.

Não pule direto para uma correção. Copie a saída completa do status em suas anotações de incidente primeiro. Depois de executar RESET REPLICA, pular uma transação ou redirecionar a réplica, algumas das melhores evidências desaparecem.

Se a Thread de E/S Estiver Parada

Quando Replica_IO_Running é No, a réplica não está lendo com sucesso da fonte. A thread SQL ainda pode estar aplicando eventos de relay mais antigos por um tempo, mas eventualmente ficará sem.

Causas comuns são:

  • O host ou porta da fonte está errado.
  • Um firewall, grupo de segurança ou regra de roteamento bloqueia a conexão.
  • A senha do usuário de replicação está errada.
  • O usuário de replicação é permitido de um host diferente do que a réplica realmente usa.
  • O log binário está desabilitado na fonte.
  • A fonte purgou o arquivo de log binário que a réplica solicitou.
  • As configurações de TLS mudaram e a réplica não pode mais autenticar.

Teste a partir do host da réplica:

mysql -h source-db.example.com -u repl_user -p

Se um login direto falhar, a replicação também falhará. Verifique a conta na fonte:

SHOW GRANTS FOR 'repl_user'@'replica_host_or_ip';

A conta precisa do privilégio REPLICATION SLAVE. O nome do privilégio ainda usa "SLAVE" nas permissões do MySQL.

Verifique também se o log binário está habilitado:

SHOW VARIABLES LIKE 'log_bin';
SHOW MASTER STATUS;

Em versões mais recentes, SHOW BINARY LOG STATUS pode estar disponível. O ponto é o mesmo: a fonte deve ter logs binários, e o arquivo solicitado ainda deve existir.

Erro 1236: Log Binário Ausente ou Ilegível

Last_IO_Errno: 1236 é um dos erros que geralmente significa que a réplica está solicitando um arquivo de log binário ou posição que a fonte não pode fornecer. A mensagem exata varia. Pode dizer que o primeiro arquivo de log não pode ser encontrado, um evento de log não pôde ser lido ou a fonte fechou a conexão durante a leitura.

O caso operacional mais comum é simples: a réplica ficou inativa por muito tempo e a fonte purgou os logs binários que ela precisava.

Verifique quais logs permanecem na fonte:

SHOW BINARY LOGS;

Em seguida, compare essa lista com o arquivo nomeado no status da réplica. Se a réplica precisa de mysql-bin.000120 e a fonte agora começa em mysql-bin.000140, a réplica não pode alcançar a partir dos logs binários.

Você tem três opções realistas:

  • Restaurar ou reconstruir a réplica a partir de um backup recente tirado da fonte.
  • Usar outra réplica que ainda tenha os dados necessários como fonte de clone, se seu processo suportar isso.
  • Se estiver usando GTID e as transações ausentes existirem em outro lugar, reconfigurar a partir de uma fonte válida que possa fornecê-las.

Não adivinhe uma posição de log mais recente apenas para fazer a replicação iniciar. Isso cria uma réplica com transações ausentes. Pode parecer saudável enquanto retorna dados errados silenciosamente.

Após a recuperação, aumente a retenção de logs binários se a capacidade do disco permitir:

[mysqld]
binlog_expire_logs_seconds=604800

Esse exemplo é cerca de 7 dias. Escolha um valor com base em quanto tempo as réplicas podem ficar offline durante manutenção ou incidentes.

Se a Thread SQL Estiver Parada

Quando Replica_SQL_Running é No, a réplica buscou eventos, mas não conseguiu aplicar um. Isso geralmente é um problema de consistência de dados, não um problema de conexão.

Leia o Last_SQL_Error completo. Geralmente informa a tabela, chave, operação com falha e, às vezes, a posição do log da fonte. Em seguida, inspecione a linha relevante na fonte e na réplica antes de alterar qualquer coisa.

Para um evento com falha em torno de uma posição de log binário conhecida, mysqlbinlog pode mostrar o evento:

mysqlbinlog --start-position=123456 --stop-position=124500 /var/lib/mysql/mysql-bin.000321

Se os logs binários da fonte não estiverem no host local, use opções remotas ou inspecione um arquivo de log copiado. Tenha cuidado com eventos baseados em linha: eles podem precisar de opções de decodificação e metadados de tabela para serem legíveis.

Erro 1062: Entrada Duplicada

Last_SQL_Errno: 1062 significa que a réplica tentou inserir ou atualizar uma linha e encontrou uma chave única que já existe.

Causas típicas incluem:

  • Alguém escreveu diretamente na réplica.
  • A réplica foi inicializada a partir do snapshot errado.
  • Um erro de replicação anterior foi ignorado.
  • As configurações de auto-incremento estão erradas em um design multi-fonte ou ativo-ativo.
  • Gravações de aplicativos foram para dois servidores graváveis por engano.

A correção tentadora é:

STOP REPLICA;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START REPLICA;

A sintaxe mais antiga usa STOP SLAVE e START SLAVE. Isso pode ser aceitável para uma réplica descartável de relatórios depois de confirmar que a linha não importa. É perigoso para uma réplica que pode ser promovida posteriormente. Pular significa que a réplica não tem mais o mesmo histórico de transações que a fonte.

Um processo mais seguro é:

  1. Identificar a tabela e chave conflitantes.
  2. Comparar a linha na fonte e na réplica.
  3. Decidir se a linha da réplica deve ser excluída, atualizada ou se a réplica deve ser reconstruída.
  4. Registrar a decisão, porque agora isso é um evento de consistência de dados.

Se a réplica é destinada a failover, reconstruir geralmente é mais limpo do que corrigir várias diferenças desconhecidas manualmente.

Erro 1032: Não é Possível Encontrar Registro

Last_SQL_Errno: 1032 geralmente significa que a réplica tentou atualizar ou excluir uma linha que não existe localmente. Esta é a imagem espelhada de muitos problemas de chave duplicada. A fonte tinha uma linha; a réplica não tinha.

Causas comuns são:

  • Uma linha foi excluída manualmente na réplica.
  • Uma transação anterior foi ignorada.
  • O dump inicial perdeu dados.
  • Filtros de replicação excluíram gravações anteriores.

Não presuma que a linha ausente é inofensiva. Se um UPDATE não consegue encontrar uma linha, a réplica já é diferente da fonte. Compare contagens e dados de amostra em torno da chave afetada. Se a tabela for pequena, um recarregamento de tabela pode ser razoável. Se for grande ou crítica, use uma ferramenta de consistência ou reconstrua a réplica.

Problemas de Autenticação e Permissão de Host

Uma falha muito comum após rotação de senha ou mudanças de rede é um erro de E/S que parece acesso negado:

Access denied for user 'repl_user'@'10.0.2.15'

O host no erro é aquele que o MySQL vê. Pode não corresponder ao nome de host que você esperava, especialmente com NAT, proxies ou rede de contêineres.

Na fonte, inspecione os usuários:

SELECT user, host, plugin FROM mysql.user WHERE user = 'repl_user';

Se a réplica conectar de 10.0.2.15, uma permissão para 'repl_user'@'replica.internal' pode não corresponder, a menos que a resolução de nomes e as permissões estejam alinhadas. Prefira padrões de host explícitos que correspondam ao seu design de rede.

Se o plugin for diferente, clientes mais antigos podem falhar contra contas que usam plugins de autenticação mais recentes. Atualizar o cliente geralmente é melhor do que enfraquecer a autenticação, mas em ambientes de versões mistas, você pode precisar de uma mudança de compatibilidade planejada.

Problemas de Log de Relay

Às vezes, a conexão da fonte está boa, mas a réplica tem corrupção de log de relay ou problemas de disco local. O erro pode mencionar uma falha de leitura de log de relay, evento truncado ou posição de log de relay.

Primeiro, verifique a saúde do disco e o espaço livre. Um disco cheio pode criar vários sintomas estranhos de replicação:

df -h
iostat -xz 1

Se o log de relay estiver corrompido, mas a fonte ainda tiver os logs binários necessários, você pode frequentemente redefinir os logs de relay e deixar a réplica buscar novamente. O comando exato depende da versão e topologia. Não execute comandos de reset casualmente; confirme que você conhece o arquivo de log da fonte e a posição que já foi executada.

Em muitos casos, esse tipo de problema é um sinal de que o host da réplica teve um problema de armazenamento subjacente. Corrija isso antes de confiar na réplica novamente.

Atraso de Replicação Nem Sempre é Falha

Seconds_Behind_Source pode ser alto enquanto ambas as threads estão em execução. Isso significa que a replicação está ativa, mas atrasada. Trate o atraso de forma diferente de uma thread parada.

Verifique:

  • O disco da réplica está saturado?
  • A fonte está gerando uma explosão de gravações?
  • Leituras longas na réplica estão competindo com a thread SQL?
  • A réplica é menor ou mais lenta que a fonte?
  • Um trabalho de backup ou snapshot começou ao mesmo tempo?

Se o atraso está diminuindo, a réplica está alcançando. Se o atraso está aumentando, remova carga ou adicione capacidade. Reiniciar uma réplica atrasada raramente corrige um gargalo sustentado de recursos.

Filtros e Replicação Multi-Fonte

Filtros de replicação podem tornar as falhas mais difíceis de ler. Uma réplica pode intencionalmente ignorar alguns bancos de dados ou tabelas, mas o aplicativo ainda pode esperar que dados relacionados existam. Se você usa filtros, inspecione-os antes de assumir que a réplica está corrompida:

SHOW REPLICA STATUS\G

Procure campos que mencionem Replicate_Do_DB, Replicate_Ignore_DB, Replicate_Do_Table ou regras de reescrita. A saída mais antiga usa os mesmos nomes gerais em SHOW SLAVE STATUS.

Filtrar é especialmente arriscado com gravações entre bancos de dados. Se uma transação atualiza app.orders e audit.order_events, mas a réplica filtra audit, a cópia resultante pode ser tecnicamente consistente com o filtro e ainda inútil para um fluxo de trabalho que espera linhas de auditoria. O log baseado em declaração pode tornar os filtros de banco de dados ainda mais surpreendentes porque o banco de dados padrão selecionado pode influenciar se um evento é replicado.

A replicação multi-fonte adiciona outra camada. Um canal pode estar saudável enquanto outro está parado. Nesse caso, verifique o status de todos os canais em vez de ler apenas o primeiro bloco de saída:

SHOW REPLICA STATUS\G

Em configurações baseadas em canal, a saída de status inclui um nome de canal. Corrija o canal com falha sem redefinir canais saudáveis. Se duas fontes podem escrever chaves sobrepostas na mesma tabela, erros de chave duplicada são frequentemente um problema de design, em vez de uma falha de replicação isolada.

Evite Desvio Oculto de Dados

A pior falha de replicação é aquela que diz Yes e ainda contém dados errados. O desvio pode acontecer após transações ignoradas, gravações diretas em réplicas, importações com falha, filtros ruins ou reparos manuais.

Para réplicas importantes, agende verificações de consistência. O pt-table-checksum do Percona Toolkit é comumente usado para isso, e o pt-table-sync pode ajudar a reparar diferenças em situações controladas. Essas ferramentas podem criar carga, então teste-as primeiro e execute-as com limites que correspondam ao seu ambiente de produção.

Também proteja as réplicas contra gravações acidentais:

[mysqld]
read_only=ON
super_read_only=ON

Use credenciais separadas para leituras de aplicativos. Não permita que usuários de aplicativos tenham privilégios amplos de gravação em réplicas "apenas por precaução".

Um Checklist Rápido para Incidentes

Use esta ordem quando a replicação quebrar:

  1. Salve a saída de SHOW REPLICA STATUS\G.
  2. Verifique se a thread de E/S ou a thread SQL parou.
  3. Leia Last_IO_Error ou Last_SQL_Error; não confie apenas no número do erro.
  4. Verifique o log de erros do MySQL para timestamps correspondentes.
  5. Para falhas de E/S, teste rede, credenciais, permissões, TLS e disponibilidade de log binário.
  6. Para falhas SQL, inspecione a linha ou tabela afetada na fonte e na réplica.
  7. Decida se deve reparar, pular com risco documentado, recarregar uma tabela ou reconstruir a réplica.
  8. Após a recuperação, execute um teste de gravação real e monitore o atraso.

A maioria das falhas de replicação do MySQL não é resolvida por um comando mágico. Elas são resolvidas preservando evidências, identificando qual thread falhou e escolhendo uma correção que não deixe você com uma réplica que está em execução, mas não é confiável.