Траблшутинг блокировок метаданных (MDL) в MySQL: поиск зависших транзакций
- Операции
ALTER TABLE,CREATE INDEXилиDROP TABLEзависают в статусеWaiting for table metadata lock. - Все последующие простые SELECT запросы к таблице выстраиваются в очередь и блокируют веб-приложение.
- Быстрое исчерпание лимита свободных соединений (
max_connections).
1. Включение сбора информации о блокировках метаданных
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME = 'wait/lock/metadata/sql/mdl';2. Поиск транзакции, удерживающей MDL блокировку
Выполните диагностический SQL-запрос:
SELECT
locked_schema, locked_table,
waiting_processlist_id, waiting_query,
blocking_processlist_id, blocking_query,
sql_kill_blocking_connection
FROM sys.schema_table_lock_waits;3. Альтернативный поиск через Performance Schema и Threads
SELECT
t.PROCESSLIST_ID AS blocking_pid,
t.PROCESSLIST_USER,
t.PROCESSLIST_HOST,
m.OBJECT_TYPE,
m.OBJECT_SCHEMA,
m.OBJECT_NAME,
m.LOCK_TYPE,
m.LOCK_STATUS
FROM performance_schema.metadata_locks m
JOIN performance_schema.threads t ON m.OWNER_THREAD_ID = t.THREAD_ID
WHERE m.LOCK_STATUS = 'GRANTED';4. Принудительное завершение блокирующей транзакции
KILL CONNECTION <blocking_pid>;5. Превентивная защита от зависания ALTER TABLE
Перед запуском миграций в сессии задайте таймаут ожидания блокировки:
SET SESSION lock_wait_timeout = 10;
ALTER TABLE users ADD COLUMN age INT; Частые вопросы (FAQ)
Почему простой незакрытый SELECT может заблокировать ALTER TABLE?
Даже операция SELECT открывает разделяемую блокировку метаданных (Shared MDL) на время транзакции. Эксклюзивный запрос ALTER TABLE встает в очередь ожидания ее закрытия, блокируя все новые поступающие запросы к этой таблице.
Что произойдет, если сработает lock_wait_timeout при выполнении ALTER?
Операция ALTER немедленно завершится с ошибкой ER_LOCK_WAIT_TIMEOUT, освободив очередь для рабочих запросов и не допустив падения всего продакшена.