Центр Диагностики & База Системных Ошибок

Решения для Windows Server, Active Directory, 1С, СУБД, Linux, Cisco, MikroTik и IP-телефонии.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, баз данных и сетевого оборудования. Перед выполнением действий обязательно создайте резервную копию. При отсутствии необходимой квалификации обратитесь к ИТ-специалистам.
MYSQL-ERR-1205 Linux / DevOps

MySQL Ошибка 1205 (HY000): Lock wait timeout exceeded (innodb_lock_wait_timeout)

Обновлено: 21.08.2026  ·  Официальная база знаний

Механизм блокировок на уровне строк (Row-Level Locking) в InnoDB

Для обеспечения транзакционной изоляции движок InnoDB накладывает эксклюзивные блокировки (X-Locks) на изменяемые строки при выполнении операций UPDATE, DELETE или SELECT ... FOR UPDATE. Если транзакция Б пытается модифицировать или заблокировать строку, которая уже удерживается незавершенной транзакцией А, транзакция Б переходит в режим ожидания (Lock Wait). Время ожидания жестко лимитируется системной переменной innodb_lock_wait_timeout (по умолчанию 50 секунд). Если за это время первая транзакция не выполнила COMMIT или ROLLBACK, транзакция Б прерывается с системной ошибкой:

«ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction»

Бизнес-риски

Массовое зависание пользовательских запросов в очереди, сбои при обновлении остатков товаров на складе, каскадное накопление открытых соединений и падение по ошибке 1040.

Сравнение таймаута блокировки (1205) и дедлока (1213)

ПараметрОшибка 1205 (Lock Wait Timeout)Ошибка 1213 (Deadlock Detected)
ПричинаТранзакция долго ждет освобождения строки без взаимного замыкания.Взаимный замкнутый цикл ожидания двух транзакций.
Время реакцииСрабатывает строго по истечении таймаута (например, через 50 сек).Срабатывает мгновенно (в течение миллисекунд).
Объем откатаПо умолчанию откатывает только упавший стейтмент (транзакция остается открытой!).Откатывает всю транзакцию целиком до точки BEGIN.

Регламент локализации блокирующей транзакции и оптимизации запросов

Шаг 1: Поиск блокирующего процесса через представление sys.innodb_lock_waits

Выполните запрос для определения точного ID потока и SQL-запроса, который держит блокировку:

-- 1. Запрос анализа блокировок (MySQL 5.7 / 8.0+):
SELECT 
    r.trx_id waiting_trx_id,
    r.trx_mysql_thread_id waiting_thread,
    r.trx_query waiting_query,
    b.trx_id blocking_trx_id,
    b.trx_mysql_thread_id blocking_thread,
    b.trx_query blocking_query
FROM performance_schema.data_lock_waits w
JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_engine_transaction_id
JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_engine_transaction_id;

-- 2. В схеме SYS (удобный человекочитаемый отчет):
SELECT 
    waiting_account, waiting_query, 
    blocking_account, blocking_query, 
    wait_age_secs, locked_table
FROM sys.innodb_lock_waits;

Шаг 2: Принудительное завершение блокирующего потока

-- Убейте поток, удерживающий транзакцию открытой (blocking_thread ID):
KILL 15420;

Шаг 3: Настройка параметров innodb_lock_wait_timeout и rollback

# 1. Уменьшение таймаута ожидания для веб-приложений (например, до 15 секунд вместо 50):
SET GLOBAL innodb_lock_wait_timeout = 15;

# 2. Включение полного отката всей транзакции при наступлении таймаута (защита целостности!):
# В my.cnf:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
innodb_lock_wait_timeout = 15
innodb_rollback_on_timeout = 1

# 3. Перезапуск службы:
sudo systemctl restart mysql

Шаг 4: Оптимизация неиндексированных UPDATE запросов

Если запрос UPDATE выполняется по неиндексированному полю, InnoDB накладывает блокировку НА ВСЮ ТАБЛИЦУ ЦЕЛИКОМ (Table-level Lock), блокируя всех остальных пользователей:

-- ОШИБКА: поле status не имеет индекса -> блокируются ВСЕ строки таблицы orders!
UPDATE orders SET processed = 1 WHERE status = 'pending';

-- ИСПРАВЛЕНИЕ: создание индекса для точечной блокировки только изменяемых строк:
ALTER TABLE orders ADD INDEX idx_status (status);

Типовые ошибки администраторов

  • Простое увеличение innodb_lock_wait_timeout до 500 секунд: Это не решает проблему, а лишь заставляет пользователей ждать по 8 минут перед получением ошибки, полностью парализуя работу пула потоков.
  • Игнорирование незакрытых транзакций в бэкенд-коде: Открытие транзакции (BEGIN), выполнение тяжелых внешних HTTP-запросов к API и последующий COMMIT держит строки базы заблокированными на десятки секунд.
База данных зависает на длительных блокировках строк?
Специалисты ITSTM проведут аудит транзакционной модели, устранят блокировки таблиц и настроят оптимальные уровни изоляции транзакций.
Практический опыт инженера: Никогда не выполняйте долгие сетевые операции (отправку email, вызовы платежных шлюзов) внутри открытой транзакции базы данных. Транзакция должна содержать исключительно быстрые атомарные SQL-операции и фиксироваться (COMMIT) как можно скорее.

Частые вопросы (FAQ)

Почему при ошибке 1205 транзакция не откатывается полностью?

По стандарту InnoDB при таймауте 1205 откатывает только последний ошибочный SQL-стейтмент. Чтобы откатывалась вся транзакция, необходимо включить innodb_rollback_on_timeout = ON.

Как уровень изоляции READ COMMITTED помогает против блокировок?

В режиме READ COMMITTED движок снимает блокировки со строк, которые были прочитаны в процессе сканирования, но не подошли под итоговые условия WHERE, а также полностью отключает блокировки промежутков Gap Locks.

Где посмотреть историю долгих блокировок в MySQL?

В выводе команды SHOW ENGINE INNODB STATUS\G найдите секцию 'TRANSACTIONS' и блок 'RECORD LOCKS'.

Как избежать блокировок при пакетном удалении старых данных?

Удаляйте данные небольшими чанками в цикле с явным LIMIT: DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY LIMIT 1000; с паузой sleep(0.1) между итерациями.