--single-transaction
Вариант mysqldump
делает сделать FLUSH TABLES WITH READ LOCK
перед началом задания резервного копирования , но только при определенных условиях. Одно из таких условий - когда вы также указываете --master-data
опцию.
В исходном коде из mysql-5.6.19/client/mysqldump.c
строки 5797:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
Чтобы получить надежную блокировку точных координат бинлога до начала транзакции повторяемого чтения, эта --master-data
опция вызывает получение этой блокировки, а затем освобождение после получения координат бинлога.
На самом деле, следует mysqldump
ли FLUSH TABLES
после a, FLUSH TABLES WITH READ LOCK
потому что выполнение обеих вещей позволяет быстрее получить блокировку чтения в случаях, когда первоначальная очистка занимает некоторое время.
...Однако...
Как только он получит координаты бинлога, mysqldump
выдает UNLOCK TABLES
инструкцию, поэтому в результате начавшегося сброса не должно быть ничего блокирующего. Ни один из потоков не должен быть Waiting for table flush
результатом транзакции, которая mysqldump
удерживается.
Когда вы видите поток в Waiting for table flush
состоянии, это должно означать, что FLUSH TABLES [WITH READ LOCK]
инструкция была выполнена и все еще выполнялась, когда запрос начинался - поэтому запрос должен ждать сброса таблицы, прежде чем он сможет выполнить. В случае списка процессов, который вы опубликовали, mysqldump
он читает из этой же таблицы, и запрос выполнялся какое-то время, но блокирующие запросы не блокировали все это время.
Все это говорит о том, что произошло что-то еще.
В Bug # 44884 есть давняя проблема, объясняющая, как FLUSH TABLES
работает внутренне. Я не был бы удивлен, если проблема все еще сохраняется, я был бы удивлен, если бы эта проблема когда-либо была «исправлена», потому что это очень сложная проблема, которую практически невозможно решить - практически невозможно действительно решить в среде с высоким уровнем параллелизма - и любая попытка исправление этого влечет за собой значительный риск поломки чего-либо другого или создания нового, другого и все еще нежелательного поведения.
Кажется вероятным, что это будет объяснением того, что вы видите.
В частности:
если у вас есть долгосрочный запрос, работающий с таблицей, и вы FLUSH TABLES
выполняете команду, то он FLUSH TABLES
будет блокироваться до тех пор, пока не будет выполнен длительный запрос.
Кроме того, любые запросы, которые начинаются после FLUSH TABLES
выдачи, будут блокироваться до FLUSH TABLES
завершения.
Кроме того, если вы убьете FLUSH TABLES
запрос, блокирующие запросы все равно будут блокировать исходный длительный запрос, который блокировал FLUSH TABLES
запрос, потому что, даже если завершенный FLUSH TABLES
запрос не завершился, эта таблица (та, или более того, связанный с долгосрочным запросом) все еще находится в процессе сброса, и эта ожидающая очистка произойдет, как только закончится длительный запрос - но не раньше.
Вероятный вывод здесь состоит в том, что другой процесс - возможно, другой mysqldump, или опрометчивый запрос, или плохо написанный процесс мониторинга попытался очистить таблицу.
Впоследствии этот запрос был прерван или заблокирован тайм-аутом неизвестного механизма, но его последствия оставались до mysqldump
завершения чтения из рассматриваемой таблицы.
Вы можете повторить это условие, пытаясь сделать так, чтобы в FLUSH TABLES
течение длительного времени выполнялся запрос. Затем запустите другой запрос, который заблокирует. Затем убейте FLUSH TABLES
запрос, который не разблокирует последний запрос. Затем убейте первый запрос или дайте ему закончить, и последний запрос будет успешно выполнен.
Как запоздалая мысль, это не связано:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Это нормально, потому что mysqldump --single-transaction
выдает сообщение a START TRANSACTION WITH CONSISTENT SNAPSHOT
, которое не позволяет создавать дамп данных, которые были изменены во время выполнения дампа. Без этого координаты бинлога, полученные в начале, были бы бессмысленными, поскольку --single-transaction
они не были бы такими, какими они себя называют . Это ни в коем случае не должно быть связано с Waiting for table flush
проблемой, поскольку эта транзакция, очевидно, не содержит блокировок.