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