MySQL и MariaDB LinuxMySQL 8.0/8.4Percona Server 8.0/8.4

MySQL: ALTER TABLE ждёт metadata lock

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Нельзя автоматически завершать первую попавшуюся сессию: длительная транзакция может содержать неподтверждённые изменения или операцию импорта. Сначала выясните владельца и согласуйте безопасное завершение.

В этой статье
  1. Что означает неисправность и в каких условиях возникает
  2. Возможные причины: как различить
  3. Пошаговая диагностика и устранение
  4. Как проверить исправление и что делать, если оно не помогло

#Что означает неисправность и в каких условиях возникает

Команда ALTER TABLE не завершается и в состоянии соединения видна надпись Waiting for table metadata lock. Случай относится к MySQL/Percona 8.x: изменение структуры обязано дождаться завершения транзакций, которые уже используют таблицу. Нельзя автоматически завершать первую попавшуюся сессию: длительная транзакция может содержать неподтверждённые изменения или операцию импорта. Сначала выясните владельца и согласуйте безопасное завершение.

#Возможные причины: как различить

Возможная причинаКак узнатьЧто делать
Незавершённая транзакцияВ другой сессии выполнялся SELECT/UPDATE внутри BEGIN и не был вызван COMMIT/ROLLBACK.В processlist есть длительное Sleep, а запрос ALTER ждёт metadata lock.Связаться с владельцем транзакции и завершить её осознанно.
Долгий запрос или фоновое чтениеОтчёт или резервная копия держит открытую транзакцию во время ALTER.Найдена сессия с длительным запросом или транзакцией.Назначить окно обслуживания и дождаться окончания.
Очередь новых запросов за ожидающим ALTERПосле начала DDL ожидание может затронуть новые запросы к той же таблице.В processlist много ожидающих соединений к одной таблице.Отменить только ожидающий ALTER при риске простоя, затем исследовать блокировку.

#Пошаговая диагностика и устранение

  1. Убедитесь, что дело именно в metadata lockВ клиенте MySQL из отдельной администраторской сессии выполните SHOW FULL PROCESSLIST; и найдите соединение с Waiting for table metadata lock. Запишите идентификатор Id, User, Time и выполняемый ALTER. Если видите Waiting for row lock или Copying to tmp table, эта инструкция не подходит: нужна диагностика другого ожидания.
  2. Проверьте, находится ли операция под нагрузкойОткройте журнал развёртывания и определите, какой процесс начал ALTER TABLE, какую таблицу он меняет и сколько времени уже ждёт. Для боевого сайта поставьте на паузу новые изменения схемы в панели развёртывания, а не блокируйте все подключения к базе. Уведомите владельца сервиса о возможной очереди запросов.
  3. Получите список удерживаемых блокировокЕсли Performance Schema включена, под доступом с правом SELECT для служебной таблицы выполните запрос к performance_schema.metadata_locks, отфильтровав OBJECT_SCHEMA и OBJECT_NAME по реальной базе и таблице. PENDING означает ожидание, GRANTED — захваченную блокировку; идентификатор OWNER_THREAD_ID сам по себе не равен Id команды KILL, поэтому не применяйте его как номер соединения.
  4. Свяжите блокировку с процессомЧтобы сопоставить владельца с Id подключения, используйте соединение metadata_locks с performance_schema.threads по THREAD_ID: поле PROCESSLIST_ID показывает нужное соединение. Если таблица metadata_locks пуста, проверьте доступность измерений Performance Schema, а затем смотрите SHOW FULL PROCESSLIST; отсутствие строк ещё не означает отсутствие блокировок.
  5. Проверьте незавершённую транзакциюПопросите владельца обнаруженного соединения проверить, есть ли там START TRANSACTION без последующего COMMIT/ROLLBACK, и не выполняет ли оно обработку платежей или заказов. Нельзя выполнять чужой COMMIT удалённо; администратор должен согласовать, следует дождаться операции либо отменить её, поскольку потеря неподтверждённых изменений допустима не всегда.
  6. При простое отмените ожидающий ALTER в своей сессииЕсли запрос ALTER запускали вы и он ещё ждёт блокировку, вернитесь в его окно mysql и нажмите Ctrl+C. Убедитесь отдельным SHOW PROCESSLIST, что ожидающий запрос исчез. Отмена ожидания способна снять очередь новых запросов; но если ALTER уже приступил к изменению таблицы, остановка может быть долгой и требует отдельной оценки.
  7. Запланируйте безопасное изменение схемыСохраните резервную копию или проверенный способ восстановления структуры, выберите окно низкой нагрузки и исключите транзакции, которые держат соединения открытыми. Проверьте на тестовой копии, поддерживает ли планируемый ALTER нужный алгоритм online DDL; не считайте любой ALTER мгновенным и не добавляйте ALGORITHM=INSTANT без проверки допустимости операции.
  8. Повторите и измерьте результатПосле согласованного завершения блокирующей операции повторите ALTER сначала в тестовой среде и затем в согласованное окно; наблюдайте за SHOW PROCESSLIST и временем ответа сайта. Если очередь сохраняется, соберите список удерживающих и ожидающих сессий с временем, передайте DBA. Для отката изменения схемы нужен отдельный проверенный план, простой ROLLBACK после успешного DDL обычно не возвращает старую структуру.
  9. Дополнительная команда по теме
    SQLКоманда
    Только чтение данных мониторинга; добавьте фильтр по имени таблицы в своём редакторе SQL после определения её имени.
    SHOW FULL PROCESSLIST;
    SELECT ml.OBJECT_SCHEMA, ml.OBJECT_NAME, ml.LOCK_STATUS, th.PROCESSLIST_ID, th.PROCESSLIST_USER, th.PROCESSLIST_INFO FROM performance_schema.metadata_locks AS ml LEFT JOIN performance_schema.threads AS th ON th.THREAD_ID = ml.OWNER_THREAD_ID WHERE ml.OBJECT_TYPE='TABLE' AND ml.LOCK_STATUS IN ('PENDING','GRANTED');

#Как проверить исправление и что делать, если оно не помогло

Успешный результат — ALTER больше не стоит в Waiting for table metadata lock, а новые запросы не образуют очередь. Если ожидание повторяется, ищите долгоживущие транзакции и перекрытие с резервным копированием, а не увеличивайте lock_wait_timeout без обоснования.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.