Как исправить проблему взаимоблокировки MySQL/Innodb в неблокирующей среде?

StackOverflow https://stackoverflow.com/questions/870097

  •  22-08-2019
  •  | 
  •  

Вопрос

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

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

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

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

[РЕДАКТИРОВАТЬ] :Кроме того, я вообще не понимаю, зачем MySQL блокировать таблицу только для того, чтобы вставить сюда новый элемент.Сначала я подумал, что виноват автоинкремент, поэтому я удалил его...но я все еще получаю ошибку.Есть ли способ запретить MySQL блокировать таблицу при вставках?

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top