Eu tenho um banco de dados que é um escravo e um mestre. por exemplo, ele replica dados de nosso site principal e, em seguida, para um conjunto de bancos de dados escravos. (esta é principalmente uma instalação de teste, portanto não é monitorada fora do horário).
No domingo de manhã, às 7h55, ele começou a executar uma INSERT
consulta. Esta é uma consulta padrão executada milhares de vezes por dia. É uma consulta única, não faz parte de uma transação. Não há gatilhos nessa tabela. Esta tabela (e todas as outras) são arquivos INNODB
.
Mas, nesta ocasião, travou. Quando cheguei ao escritório hoje, ele estava funcionando há 24 horas (aparentemente). E a replicação estava um dia atrasada.
No entanto, quando olhei nos logs binários, apareceu como COMMIT
ed.
#160814 7:55:25 server id 21 end_log_pos 103319397 Query thread_id=635785334 exec_time=4294967294 error_code=0
SET TIMESTAMP=1471157725/*!*/;
INSERT INTO tablename . . .
/*!*/;
# at 103319397
#160814 7:55:25 server id 21 end_log_pos 103319424 Xid = 284047583
COMMIT/*!*/;
# at 103319424
Eu verifiquei os bancos de dados do Slave, e estava presente lá como seria de esperar.
Eu tenho um sistema de monitoramento que registra (entre outras coisas) a lista de processos e mostra que, para essa INSERT
consulta, ela estava permanentemente presa em STATE = UPDATE
.
Eu também verifiquei slow query log
para ver se estava lá, e não estava.
Meu entendimento era que uma consulta não poderia ser gravada binary log
até que estivesse commmited
no mestre, então alguém pode explicar o que aconteceu aqui?
Houve um efeito negativo no sistema de teste, uma vez fora, que tentou se conectar às 8h38 desta manhã, a primeira SELECT
consulta também travou e recusou todas as conexões. Então fui forçado a reiniciar o banco de dados. Nesse ponto, ele executou a recuperação de falhas e continuou como se nada tivesse acontecido.
É MySQL 5.5.47 e usando Replicação Baseada em Instrução.
bem, isso não explica por que o banco de dados travou, mas responde parte da minha pergunta:
https://www.packtpub.com/books/content/setting-mysql-replication-high-availability
Embora, agora acabei de ler o seguinte:
As instruções SQL não são
que é do livro 'Understanding MySQL Internals'.
Se você estiver obtendo informações conflitantes de fontes diferentes, use a documentação oficial:
http://dev.mysql.com/doc/refman/5.5/en/binary-log.html
Isso significa que há uma janela estreita na qual uma falha pode fazer com que uma transação não confirmada exista no log binário, mas não no banco de dados. Isso parece ser o que aconteceu no seu caso.
Em uma nota lateral, é importante entender o innodb_support_xa, que é um modelo de confirmação de duas fases - as instruções são preparadas primeiro e o cache da transação é aplicado ao log binário na fase 1 -> na fase 2, uma vez que o trx é confirmado -> o mecanismo de armazenamento grava as declarações preparadas em armazenamento/disco seguro (dependendo do sync_binlog). Após a fase 2, os bloqueios na tabela em questão são liberados.
Nota: a confirmação da transação não pode falhar mesmo se o servidor travar após a fase 1, pois durante a recuperação, o servidor MySQL diz ao InnoDB para concluir todas as transações preparadas que foram gravadas com sucesso no log binário e trunca o log binário para a última posição válida. Isso garante que o log binário reflita os dados exatos das tabelas InnoDB e, portanto, o escravo permaneça em sincronia com o mestre porque não recebe uma instrução que foi revertida.