SET GLOBAL SLAVE_NET_TIMEOUT = 60;
STOP SLAVE;
START SLAVE;
Você está certo em ser cético quanto ao fato de que isso resolverá o problema, já que nenhum tempo limite parece estar ocorrendo ... nem assim você deseja que ocorra um, mas essa ainda deve ser a solução. Eu vou explicar.
Quando a replicação parece estar paralisada sem erros, IO = Sim, SQL = Sim, Seconds_Behind_Master = 0, isso implica em uma conexão de replicação suspensa. O escravo acha que está conectado e acha que nenhum evento novo chegou.
Na replicação assíncrona nativa do MySQL, o escravo é responsável por iniciar a conexão com o mestre e, em seguida, sua função torna-se passiva - à medida que ocorrem eventos de replicação, o mestre envia autonomamente os eventos de replicação para o escravo através dessa conexão. , na camada 7, não faz nada em resposta. O TCP, é claro, mas nem o mestre nem o escravo estão cientes disso. Até que um evento de replicação ocorra, a conexão é simplesmente ociosa, sem interação. Contanto que nenhum dos lados veja nada parecido com um TCP FIN
ou RST
fechando a conexão, supõe-se que a conexão esteja ativa.
Isso é interrompido em períodos de baixo tráfego, se mestre e escravo estiverem conectados por qualquer equipamento que manuseie conexões TCP de maneira stateful - firewalls, dispositivos NAT, grupos de segurança EC2 - porque a capacidade de estado geralmente implica temporizadores de tempo limite. Se uma conexão estiver ociosa por muito tempo, a "rede" (termo geral que usarei para conectar coisas a outras coisas) removerá a conexão de suas tabelas de estado - a conexão é "esquecida". Quinze minutos é um valor comumente encontrado.
Quando esse tempo limite ocorre, a rede geralmente não faz nada, além de simplesmente remover a conexão de suas estruturas de memória interna. Nada acontece tipicamente sobre o fio. Supõe-se que as partes da conexão a abandonaram ou que o tráfego foi movido para outra rede, de modo que o dispositivo que está limpando sua memória da conexão - corretamente - não tenta ativamente avisar aos outros nós que a conexão não vai mais ser viável.
Então, na próxima vez que o mestre enviar um evento, após o tempo limite ter expirado, a rede provavelmente responderá redefinindo essa conexão "desconhecida" na direção do mestre, mas não na direção do escravo, porque o mestre é o único que iniciou o pacote que fazia parte de uma conexão "desconhecida". Então o escravo acha que tem uma conexão, quando na verdade não há nada do outro lado do tubo.
Definir slave_net_timeout
resolve isso de forma óbvia e um caminho não óbvio. O não-óbvio é aquele em que estamos particularmente interessados, enquanto o óbvio se torna nosso substituto.
Quando um escravo se conecta a um mestre, ele pede ao mestre para enviar mensagens de pulsação. As pulsações são eventos de replicação simulados que não são realmente gravados no log binário do mestre ou no log de retransmissão do escravo. Eles são gerados somente quando nenhum evento de replicação real ocorreu para MASTER_HEARTBEAT_PERIOD
segundos.
MASTER_HEARTBEAT_PERIOD
, se não definido explicitamente com CHANGE_MASTER_TO
, o padrão é slave_net_timeout / 2
.
Portanto, definir a contribuição não óbvia de slave_net_timeout
para a solução é que o mestre agora enviará tráfego ativamente para manter uma conexão inativa viva a cada 30 segundos (60/2), com o retorno sendo depois de 60 segundos de nada, o escravo soltará automaticamente a conexão e se reconectará ao mestre - efetivamente, da mesma forma que você está fazendo, parando e iniciando o escravo - embora isso nunca aconteça se a conexão estiver intacta, porque o mestre estará enviando esses batimentos cardíacos conforme necessário.
Se isso resolver seu problema, lembre-se de que você também precisa alterar slave_net_timeout
persistent atualizando my.cnf
e reiniciando o servidor - caso contrário, a configuração será revertida na próxima vez em que o servidor for reiniciado e o valor padrão antes que o MySQL 5.7 seja 3600.
Você poderia, alternativamente, simplesmente alterar MASTER_HEARTBEAT_PERIOD
para um valor menor, mas isso só corrige metade do problema. Quando a conexão realmente falha, o escravo demora muito para notar.
Não relacionado: observe que MASTER_CONNECT_RETRY = 5
é muito baixo. Você quer isso muito mais alto, ou o escravo pode desistir do mestre rapidamente demais durante uma situação de falta de energia.