Как обнаружить взаимоблокировки в Mysql / innodb? - PullRequest
12 голосов
/ 13 марта 2009

Я знаю, что при использовании транзакций в Innodb неизбежно возникают взаимоблокировки и что они безвредны, если они корректно обрабатываются кодом приложения - «просто попробуйте снова», как говорится в руководстве.

Так что мне было интересно - как вы обнаруживаете тупики? Выдает ли тупик какой-либо специальный номер ошибки mysql? Я использую расширение mysqli PHP, если это имеет значение.

Спасибо.

Редактировать: решение найдено, см. Комментарии

Ответы [ 7 ]

16 голосов
/ 18 января 2011

«ПОКАЗАТЬ СТАТУС ДВИГАТЕЛЯ INNODB» из клиента командной строки MySQL (не браузера запросов) предоставит вам информацию о взаимоблокировках.

Взаимные блокировки также могут быть вызваны незафиксированными транзакциями (обычно программными ошибками), и человек, выполняющий незафиксированную транзакцию, не увидит проблему, так как он будет работать нормально (через их данные не будут зафиксированы).

13 голосов
/ 13 марта 2009

http://dev.mysql.com/doc/refman/5.0/en/innodb-error-codes.html

1213 (ER_LOCK_DEADLOCK)

Транзакция тупиковая. Вы должны повторить сделка.

5 голосов
/ 25 июля 2012

Попробуйте использовать MONyog . Включите опцию MONyog «Мониторинг тупиков», чтобы отслеживать тупики, сообщаемые INNODB STATUS. MONyog отправит пользователю уведомление, когда возникнет новая тупиковая ситуация. enter image description here

5 голосов
/ 13 марта 2009

Попробуйте MaatKit . У него есть тупиковый регистратор.

1 голос
/ 18 мая 2015

Если вы на Mac:

$ brew install percona-toolkit

$ pt-deadlock-logger -uroot --ask-pass localhost

1 голос
/ 06 июля 2009

Попробуйте innotop, обнаружит для вас тупик.

0 голосов
/ 28 марта 2019

Недавно я создал очень простую проверку на наличие взаимоблокировок для реализации дымового теста веб-приложения. Код можно значительно улучшить, но пока он работает. См. https://dev.mysql.com/doc/refman/8.0/en/innodb-standard-monitor.html для получения дополнительной информации о выводе используемого запроса ниже.

$status = DB::select("SHOW ENGINE INNODB STATUS")["Status"]??null;

if(strpos($status,"LATEST DETECTED DEADLOCK") !== false)
{
  trigger_error("LATEST DETECTED DEADLOCK section present in output of SHOW ENGINE INNODB STATUS");
}

if(strpos($status,"LATEST FOREIGN KEY ERROR") !== false)
{
  trigger_error("LATEST FOREIGN KEY ERROR section present in output of SHOW ENGINE INNODB STATUS");
}
...