La --single-transaction
opción de mysqldump
hace hacer FLUSH TABLES WITH READ LOCK
antes de iniciar la tarea de respaldo , pero sólo bajo ciertas condiciones. Una de esas condiciones es cuando también especificas la --master-data
opción.
En el código fuente, desde la mysql-5.6.19/client/mysqldump.c
línea 5797:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
Para obtener un bloqueo sólido en las coordenadas precisas de binlog antes de comenzar la transacción de lectura repetible, la --master-data
opción activa este bloqueo que se obtendrá y luego se liberará una vez que se hayan obtenido las coordenadas de binlog.
De hecho, mysqldump
hace un FLUSH TABLES
seguido por un FLUSH TABLES WITH READ LOCK
porque hacer ambas cosas permite que el bloqueo de lectura se obtenga más rápido en los casos en que el enjuague inicial toma algún tiempo.
...sin embargo...
Tan pronto como haya obtenido las coordenadas de binlog, mysqldump
emite una UNLOCK TABLES
declaración, por lo que no debería haber nada bloqueado como resultado del vaciado que inició. Tampoco debe haber ningún subproceso Waiting for table flush
como resultado de la transacción que se mysqldump
está reteniendo.
Cuando vea un subproceso en el Waiting for table flush
estado, eso debería significar que la FLUSH TABLES [WITH READ LOCK]
instrucción se emitió y aún se estaba ejecutando cuando se inició la consulta, por lo que la consulta debe esperar el vaciado de la tabla antes de que pueda ejecutarse. En el caso de la lista de procesos que ha publicado, mysqldump
está leyendo esta misma tabla, y la consulta se ha estado ejecutando durante un tiempo, sin embargo, las consultas de bloqueo no se han bloqueado durante tanto tiempo.
Todo esto sugiere que algo más ha sucedido.
Hay un problema de larga data explicado en el Bug # 44884 con la forma en que FLUSH TABLES
funciona internamente. No me sorprendería si el problema persiste, me sorprendería si este problema alguna vez se "soluciona" porque es un problema muy complejo de resolver, prácticamente imposible de solucionar en un entorno de alta concurrencia, y cualquier intento de arreglarlo conlleva un riesgo significativo de romper algo más, o crear un comportamiento nuevo, diferente y aún indeseable.
Parece probable que esta sea la explicación de lo que estás viendo.
Específicamente:
si tiene una consulta de larga duración ejecutándose en una tabla y emite FLUSH TABLES
, FLUSH TABLES
se bloqueará hasta que se complete la consulta de larga duración.
además, cualquier consulta que comience después de que FLUSH TABLES
se emita se bloqueará hasta que FLUSH TABLES
se complete.
Además, si matas a la FLUSH TABLES
consulta, las consultas que se están bloqueando aún bloquear en el original de consulta de larga duración, la que estaba bloqueando la FLUSH TABLES
consulta, porque a pesar de los muertos FLUSH TABLES
consulta no terminó, esa tabla (el uno, o más, involucrado con la consulta de larga duración) todavía está en proceso de ser vaciado, y ese vaciado pendiente va a suceder tan pronto como finalice la consulta de larga duración, pero no antes.
La conclusión probable aquí es que otro proceso, tal vez otro mysqldump, o una consulta mal aconsejada, o un proceso de monitoreo mal escrito, intentó eliminar una tabla.
Esa consulta fue posteriormente eliminada o expirada por un mecanismo desconocido, pero sus efectos posteriores persistieron hasta que mysqldump
terminó de leer la tabla en cuestión.
Puede replicar esta condición intentando FLUSH TABLES
mientras una consulta de larga duración está en proceso. Luego comience otra consulta, que bloqueará. Luego elimine la FLUSH TABLES
consulta, que no desbloqueará la última consulta. Luego elimine la primera consulta o deje que finalice, y la consulta final se ejecutará con éxito.
Como una ocurrencia tardía, esto no está relacionado:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Eso es normal, porque mysqldump --single-transaction
emite un START TRANSACTION WITH CONSISTENT SNAPSHOT
, que evita que arroje datos que se modificaron mientras el volcado estaba en progreso. Sin eso, las coordenadas de binlog obtenidas al principio no tendrían sentido, ya --single-transaction
que no serían lo que dicen ser. Esto no debería en ningún sentido estar relacionado con el Waiting for table flush
problema, ya que esta transacción obviamente no tiene bloqueos.