Манекены руководство по блокировке в innodb - PullRequest
2 голосов
/ 13 мая 2010

Типичная документация по блокировке в innodb слишком запутанная. Я думаю, что будет очень полезно иметь «справочник манекенов для блокировки innodb»

Я начну и соберу все ответы как вики:

  • Столбец необходимо проиндексировать перед применением блокировки на уровне строк.
    • ПРИМЕР: удалить строку, где column1 = 10; заблокирует таблицу, если не будет проиндексирован column1

1 Ответ

2 голосов
/ 13 мая 2010

Вот мои заметки о работе с поддержкой MySQL по недавней странной проблеме блокировки (версия 5.1.37):

Все строки и записи индекса, пройденные для изменения строк, будут заблокированы. Это покрыто в:

http://dev.mysql.com/doc/refman/5.1/en/innodb-locks-set.html

"Чтение блокировки, UPDATE или DELETE обычно устанавливают блокировки записи для каждой индексной записи, которая сканируется при обработке оператора SQL. Не имеет значения, есть ли в операторе условия WHERE, которые исключают строку InnoDB не помнит точное условие WHERE, но знает только, какие диапазоны индексов были отсканированы ... Если у вас нет индексов, подходящих для вашего оператора, и MySQL должен сканировать всю таблицу, чтобы обработать оператор, каждая строка таблицы блокируется. , который, в свою очередь, блокирует все вставки других пользователей в таблицу. "

Это большая головная боль, если это правда.

Это так. Обходной путь, который часто полезен, должен сделать:

ОБНОВЛЕНИЕ, в зависимости от того, что установлено для чего-либо, где находится первичный ключ (выберите первичный ключ из того, где ограничения располагаются по первичному ключу);

Внутренний выбор не должен принимать блокировки, и тогда обновление будет выполнять меньше работы для обновления. Предложение order by гарантирует, что обновление выполняется в порядке первичного ключа, чтобы соответствовать физическому порядку InnoDB, что является самым быстрым способом сделать это.

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

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

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

Если возможно, используйте режим изоляции транзакции READ COMMITTED. См:

http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html

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

Две известные проблемы:

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

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

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

http://bugs.mysql.com/bug.php?id=36569

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...