--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супроводжується тим, 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проблемою, оскільки ця транзакція, очевидно, не має жодних блокувань.