A --single-transaction
opção de mysqldump
faz um FLUSH TABLES WITH READ LOCK
antes de iniciar a tarefa de backup, mas apenas sob certas condições. Uma dessas condições é quando você também especifica a --master-data
opção.
No código-fonte, mysql-5.6.19/client/mysqldump.c
na linha 5797:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
Para obter um bloqueio sólido nas coordenadas precisas do binlog antes de iniciar a transação de leitura repetível, a --master-data
opção aciona esse bloqueio para ser obtido e liberado depois que as coordenadas do log de bin são obtidas.
De fato, mysqldump
faz um FLUSH TABLES
seguido de um FLUSH TABLES WITH READ LOCK
porque fazer as duas coisas permite que o bloqueio de leitura seja obtido mais rapidamente nos casos em que a liberação inicial leva algum tempo.
...Contudo...
Assim que ele obtém as coordenadas do binlog, mysqldump
emite uma UNLOCK TABLES
instrução, portanto não deve haver nada bloqueando como resultado do flush iniciado. Nenhum encadeamento deve ser o Waiting for table flush
resultado da transação que mysqldump
está retendo.
Quando você vê um segmento no Waiting for table flush
estado, que deve significar que a FLUSH TABLES [WITH READ LOCK]
declaração foi emitida e ainda estava correndo quando a consulta começou - para que a consulta tem que esperar para o flush mesa, antes que ele possa executar. No caso da lista de processos que você postou, mysqldump
está lendo essa mesma tabela e a consulta está em execução há um tempo, mas as consultas de bloqueio não estão bloqueando há tanto tempo.
Tudo isso sugere que algo mais aconteceu.
Há um problema de longa data explicado no Bug # 44884 com a maneira como FLUSH TABLES
funciona internamente. Eu não ficaria surpreso se o problema ainda persistir, ficaria surpreso se esse problema for "corrigido" porque é um problema muito complexo de resolver - praticamente impossível de ser corrigido em um ambiente de alta simultaneidade - e qualquer tentativa de corrigi-lo acarreta um risco significativo de quebrar outra coisa ou criar um comportamento novo, diferente e ainda indesejável.
Parece provável que esta seja a explicação para o que você está vendo.
Especificamente:
se você tiver uma consulta de longa execução em uma tabela e emitir um FLUSH TABLES
, o FLUSH TABLES
bloco será bloqueado até que a consulta de longa duração seja concluída.
Além disso, todas as consultas iniciadas após a FLUSH TABLES
emissão serão bloqueadas até a FLUSH TABLES
conclusão.
Além disso, se você matar a FLUSH TABLES
consulta, as consultas que estão bloqueando ainda serão bloqueadas na consulta de longa execução original, aquela que estava bloqueando a FLUSH TABLES
consulta, porque, embora a FLUSH TABLES
consulta finalizada não tenha terminado, essa tabela (a única ou mais, envolvido com a consulta de execução longa) ainda está em processo de liberação, e essa liberação pendente acontecerá assim que a consulta de execução longa terminar - mas não antes.
A provável conclusão aqui é que outro processo - talvez outro mysqldump, ou uma consulta não recomendada, ou um processo de monitoramento mal escrito tentou liberar uma tabela.
Essa consulta foi posteriormente eliminada ou expirada por um mecanismo desconhecido, mas seus efeitos posteriores permaneceram até mysqldump
terminar a leitura da tabela em questão.
Você pode replicar essa condição tentando FLUSH TABLES
enquanto uma consulta de longa execução está em processo. Em seguida, inicie outra consulta, que bloqueará. Em seguida, mate a FLUSH TABLES
consulta, que não desbloqueará a consulta mais recente. Em seguida, elimine a primeira consulta ou deixe-a terminar, e a consulta final será executada com êxito.
Como uma reflexão tardia, isso não tem relação:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Isso é normal, porque mysqldump --single-transaction
emite a START TRANSACTION WITH CONSISTENT SNAPSHOT
, o que impede que ele despeje dados que foram alterados enquanto o despejo estava em andamento. Sem isso, as coordenadas de binlog obtidas no início não teriam sentido, pois --single-transaction
não seria o que afirma ser. Em nenhum sentido, isso não deve estar relacionado ao Waiting for table flush
problema, pois essa transação obviamente não possui bloqueios.