A replicação do GTID do Mysql parou de funcionar

3

Eu configurei a replicação mysql gtid entre mestre e escravo. O interessante é que eu encontrei a replicação parou de funcionar depois de vários minutos, e eu tenho que usar stop slave e start slave para reiniciar a replicação do mysql. Alguém pode me dizer o que causa esse problema?

mudar mestre no escravo:

mysql> change master to
                -> master_host = 'master.com',
                -> master_user = 'replica',
                -> master_password = 'password',
                -> master_port = 3306,
                -> MASTER_CONNECT_RETRY = 5,
                -> MASTER_RETRY_COUNT = 0,
                -> MASTER_AUTO_POSITION=1;

Arquivo de configuração principal:

[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir         = /data/mysql_data
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking

binlog-format   = MIXED

interactive_timeout=180
wait_timeout=180

key_buffer      = 16M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8

myisam-recover         = BACKUP
max_connections        = 300

query_cache_limit   = 1M
query_cache_size        = 16M

general_log             = 1
log_error = /var/log/mysql/error.log
server-id       = 1
log_bin         = /var/log/mysql/mysql-bin.log
log_bin_trust_function_creators = 1
log-slave-updates   = true

# enable GTID
gtid-mode = on
enforce-gtid-consistency = true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
binlog-checksum=CRC32
master-verify-checksum=1

expire_logs_days    = 10
max_binlog_size     = 100M

Configuração do escravo:

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /data/mysql_data
tmpdir         = /data/mysql_data/tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking

binlog-format   = MIXED

interactive_timeout=180
wait_timeout=180

key_buffer              = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
max_connections        = 100

query_cache_limit       = 1M
query_cache_size        = 16M

general_log             = 1
log_error = /var/log/mysql/error.log
server-id               = 2

log_bin                 = /var/log/mysql/mysql-bin.log
log_bin_trust_function_creators = 1
log-slave-updates       = true

# enable GTID
gtid-mode = on
enforce-gtid-consistency = true
sync-master-info=1
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1

expire_logs_days        = 10
max_binlog_size         = 100M

Eu não vi nenhum problema em show slave status , mas o problema ainda está me interrompendo. Qualquer ajuda seria agradecida antecipadamente.

    
por technoob 16.10.2016 / 05:15

1 resposta

2

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.

    
por 16.10.2016 / 17:45