#Что означает ошибка
Deadlock found
Взаимная блокировка транзакций. Повторите транзакцию, обновляйте строки в едином порядке и сокращайте время удержания.
#Причины и признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Разный порядок | В случае «MySQL: ERROR 1213 — Deadlock found when trying to get lock» проверьте наличие причины «Разный порядок» по исходному действию и связанному сообщению; переходить к исправлению стоит после её подтверждения. | Упорядочите |
| Долгие транзакции | В случае «MySQL: ERROR 1213 — Deadlock found when trying to get lock» проверьте наличие причины «Долгие транзакции» по исходному действию и связанному сообщению; переходить к исправлению стоит после её подтверждения. | Сократите. Конкретное действие зависит от проверки причины «Долгие транзакции», описанной в пошаговой инструкции. |
| Нет индекса | В случае «MySQL: ERROR 1213 — Deadlock found when trying to get lock» проверьте наличие причины «Нет индекса» по исходному действию и связанному сообщению; переходить к исправлению стоит после её подтверждения. | Добавьте. Конкретное действие зависит от проверки причины «Нет индекса», описанной в пошаговой инструкции. |
| Нет повтора | В случае «MySQL: ERROR 1213 — Deadlock found when trying to get lock» проверьте наличие причины «Нет повтора» по исходному действию и связанному сообщению; переходить к исправлению стоит после её подтверждения. | Повторяйте |
#Пошаговое решение
- Определите причинуВ журнале MySQL или приложения найдите
ERROR 1213 Deadlock found when trying to get lock; на сервере с правами администратора выполнитеSHOW ENGINE INNODB STATUS\Gв MySQL CLI и найдите разделLATEST DETECTED DEADLOCK. Сохраните запросы, таблицы и порядок блокировок без публикации конфиденциальных данных. - Выполните подходящее исправлениеСравните порядок изменения таблиц в двух конфликтующих транзакциях. На стенде добейтесь одинакового порядка получения блокировок и сократите время между началом транзакции и COMMIT. Добавьте нужные индексы после проверки EXPLAIN, чтобы транзакции не захватывали больше строк, чем необходимо.
- Проверьте другие возможные причиныЕсли число взаимных блокировок невелико и приложение поддерживает безопасный повтор, реализуйте ограниченный повтор всей транзакции после 1213 с небольшой случайной задержкой. Это допустимо только для идемпотентного сценария с корректным откатом; не повторяйте внешние платежи или отправку сообщений без проверки факта выполнения.
- Убедитесь в результатеВыполните тест конкурирующих запросов на копии данных, убедитесь в отсутствии потерянных обновлений и неправильного порядка операций. Отдельно наблюдайте количество 1213 после развёртывания; полностью исключить взаимные блокировки в конкурентных БД не всегда возможно, но приложение должно их обрабатывать.
#Если проблема осталась
Если «MySQL: ERROR 1213 — Deadlock found when trying to get lock» повторяется, сохраните время, состояние подключения и точный текст ошибки. Не меняйте сразу несколько настроек — иначе станет трудно понять, какое действие повлияло на результат.