Как исправить эту проблему взаимоблокировки MySQL / Innodb в неблокирующей среде? - PullRequest
1 голос
/ 15 мая 2009

Мы используем MySQL с хранилищем Innodb Engine. У нас есть «выравниваемая» среда, которая отправляет несколько одновременных запросов к таблице. В основном это работает так: У нас есть функция find_or_insert, которая делает это: - находить() -> на результат, если пусто -> вставить -> по результату find ()

Мы используем неблокирующий драйвер MySQL, поэтому, по сути, когда мы запускаем этот небольшой алгоритм более одного раза одновременно, он запускает все находки перед вставкой первого результата ... и т. Д.

К сожалению, мы получаем эти ошибки: «Обнаружен тупик при попытке получить блокировку; попробуйте перезапустить транзакцию»

Кто-нибудь может помочь с этим?

[EDIT]: Кроме того, я на самом деле не понимаю, зачем MySQL нужно блокировать таблицу, просто чтобы вставить новый элемент здесь. Изначально я считал, что виновником здесь является автоинкремент, поэтому я удалил его ... но я все еще получаю сообщение об ошибке. Есть ли способ предотвратить блокировку таблицы MySQL на вставках?

Ответы [ 3 ]

1 голос
/ 15 мая 2009

Попробуйте справочное руководство mysql для диагностики и устранения неисправностей. Похоже, вы делаете кеш. Вероятной причиной может быть то, что многие клиенты одновременно обращаются к таблице, пытаясь создать «первую версию» (то есть «пустую вставку»). Может быть, вы могли бы добавить псевдослучайную задержку или координировать создателей, чтобы вы не получали много одновременных вызовов create для БД?

РЕДАКТИРОВАТЬ: Вы видели эту страницу? Похоже, вам нужно установить параметр my.cnf, чтобы отключить блокировки для каждой таблицы с помощью innodb. Однако в основном я предлагал, чтобы ваш тест не был представлен, поскольку в нем может быть гораздо больше авторов, чем в реальной ситуации. Если вы запустите 100 потоков с пустой таблицей, все они сразу же заблокируются при создании (возможно, даже для того же значения). Это намного хуже, чем в обычной ситуации, когда у вас лучше разброс по клавишам, меньше пропусков и гораздо больший процент операций чтения. Если это ожидаемое поведение (т. Е. Такое поведение будет активным), я бы предложил добавить стратегию отката в операторах create.

0 голосов
/ 15 мая 2009

Я изменяю свой ответ, чтобы отразить, что вопрос пересмотрен. Похоже, что это проблема только одновременных вставок, а не зависимость от поведения поиска.

Насколько я понимаю, InnoDB блокирует строки на вставках, и вы не можете отключить это. Однако вы [править] не можете использовать INSERT DELAYED. Я только что прочитал, что это не доступно на InnoDB.

http://dev.mysql.com/doc/refman/5.0/en/insert-delayed.html

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

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

0 голосов
/ 15 мая 2009

Вам нужно, чтобы эти запросы выполнялись по одному, поэтому, возможно, прекратите использовать этот неблокирующий драйвер. Или реализовать свой собственный механизм блокировки. Подождите, пока один из них закончится, прежде чем переходить к следующему.

Вы не сказали, что это неразумно или что вам по каким-то причинам нужно, чтобы эти вещи продвигались так быстро.

...