Когда InnoDB делает тайм-аут вместо сообщения о взаимоблокировке? - PullRequest
3 голосов
/ 28 сентября 2010

У меня ошибка «Ошибка ожидания ожидания превышена» в MySQL, которую я не могу воспроизвести или диагностировать. Я уверен, что это тупик (в отличие от транзакции, которая захватывает блокировку, а затем переворачивает ее большие пальцы), потому что мои журналы показывают, что другой процесс запускался одновременно, также зависал, а затем продолжался при первом тайм-ауте. Но обычно InnoDB обнаруживает взаимные блокировки без тайм-аута. Поэтому я пытаюсь понять, почему этот тупик не был обнаружен.

Обе транзакции используют сериализуемый уровень изоляции. (У меня есть четкое представление о блокировке InnoDB на этом уровне изоляции.) В транзакции используется одна не-InnoDB (MyISAM) таблица, которую я вставляю и обновляю. Тем не менее, я не понимаю, как это может быть вовлечено в тупик, потому что я считаю, что MyISAM просто берет блокировку таблицы во время вставок и обновлений (а затем немедленно освобождает ее, так как MyISAM не является транзакционной), поэтому никакая другая блокировка не выполняется, пока эта удерживается блокировка стола.

Так что я убежден, что в тупике задействованы только таблицы InnoDB, что возвращает меня к вопросу о том, почему он не был обнаружен. Документация MySQL (http://dev.mysql.com/doc/refman/5.1/en/innodb-deadlock-detection.html) подразумевает, что обнаружение взаимоблокировок почти всегда работает. Проблемы, которые я обнаружил при поиске, включают в себя такие вещи, как явная «таблица блокировок», «изменение таблицы» и «вставка с задержкой». эти вещи, просто вставляет, обновляет и выбирает (некоторые из моих выборов «для обновления»).

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

Любые другие советы для диагностики этого? Я использую mysql 5.1.49.

Ответы [ 2 ]

3 голосов
/ 28 сентября 2010

Один совет: вы можете использовать SHOW INNODB STATUS, чтобы, как вы уже догадались, показать состояние механизма InnoDB.

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

mysqladmin debug также может выводить полезную информацию об отладке блокировки.

Третий прием - создать таблицу с волшебным именем innodb_lock_monitor, как описано в http://dev.mysql.com/doc/refman/5.1/en/innodb-monitors.html, которая дает более подробную отладку блокировки.

НТН!

UPDATE

Возможно, он не обнаруживает взаимоблокировку, поскольку на самом деле это не взаимоблокировка, но, скорее всего, один процесс ожидает блокировки строки в строке, заблокированной другим процессом. Из руководства по переменной innodb_lock_wait_timeout:

Тайм-аут в секундах и InnoDB транзакция может ожидать блокировки строки прежде чем сдаться. Значением по умолчанию является 50 секунд Транзакция, которая пытается чтобы получить доступ к строке, которая заблокирована другая транзакция InnoDB будет зависать в течение максимально этого много секунд до выдав следующую ошибку:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction Когда тайм-аут ожидания блокировки происходит, текущее заявление не выполняется. текущая транзакция не свернута назад. (До MySQL 5.0.13 InnoDB откатил всю транзакцию, если тайм-аут ожидания блокировки произошел.

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

1 голос
/ 30 сентября 2010

Мне удалось воспроизвести и диагностировать проблему.Это тупик с участием MyISAM и InnoDB.Похоже, это взаимодействие между транзакционной блокировкой строки InnoDB и нетранзакционной блокировкой таблицы MyISAM.Я отправил сообщение об ошибке: http://bugs.mysql.com/bug.php?id=57118. В любом случае, я считаю, что ответ на мой первоначальный вопрос заключается в том, что InnoDB всегда должен обнаруживать взаимоблокировки, если в MySQL нет ошибки.; -)

...