Есть ли способ не получить блокировку в MySQL? - PullRequest
0 голосов
/ 12 ноября 2010

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

Я столкнулся с проблемой, которая выдает мне следующую ошибку: «SQLSTATE [40001]: сбой сериализации: 1213 Обнаружен тупик при попытке получить блокировку; попробуйте перезапустить транзакцию»

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

Действительно, я просто пытаюсь читать другие таблицы, а не записывать в них, есть ли способ создать запрос, но не запрашивать блокировку?

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

Ответы [ 2 ]

2 голосов
/ 12 ноября 2010

Вы можете попробовать использовать INSERT DELAYED , вот что он делает:

Когда клиент использует INSERT DELAYED, он сразу получает одобрение от сервера, истрока ставится в очередь для вставки, когда таблица не используется каким-либо другим потоком.

Если вы хотите видеть данные в смешанном состоянии, вы можете изменить уровень изоляции транзакции

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- Problematic SELECT query goes here --
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Я узнал, что один из другого ответа SO от JonЭриксон

2 голосов
/ 12 ноября 2010

Если вы находитесь в режиме изоляции транзакции REPEATABLE_READ (который используется по умолчанию), то выбор не должен создавать никаких блокировок.Это нормально.

Однако, если вы используете вставку ... выберите, конечно, вы получите блокировки в таблице назначения.

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

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

идей для рассмотрения:

  • Использование внешней блокировки (для innodb)чтобы сериализовать процесс для нескольких копий
  • Измените режим изоляции транзакции на READ_COMMITTED для этой операции - если вы понимаете, что это значит, и можете это допустить.)

Вы можете увидеть, что делали транзакции, связанные с тупиком, используя SHOW ENGINE INNODB STATUS, сразу после тупика.

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

Обязательно выполните любое тестирование в непроизводственной системе!

...