Любой способ выбрать, не вызывая блокировки в MySQL? - PullRequest
119 голосов
/ 27 мая 2009

Запрос:

SELECT COUNT(online.account_id) cnt from online;

Но онлайн-таблица также модифицируется событием, поэтому часто я вижу блокировку при запуске show processlist.

Есть ли в MySQL грамматика, которая может сделать оператор выбора не вызывающим блокировки?

И я забыл упомянуть выше, что он находится в ведомой базе данных MySQL.

После того, как я добавил в my.cnf:transaction-isolation = READ-UNCOMMITTED раб встретит с ошибкой:

Ошибка 'Двоичная регистрация невозможна. Сообщение: Уровень транзакции «READ-UNCOMMITTED» в InnoDB небезопасен для режима binlog «STATEMENT» по запросу

Итак, есть ли совместимый способ сделать это?

Ответы [ 8 ]

155 голосов
/ 28 мая 2009

Найдена статья под названием "MYSQL WITH NOLOCK"

https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx

в MS SQL Server вы должны сделать следующее:

SELECT * FROM TABLE_NAME WITH (nolock)

и эквивалент MYSQL равен

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;

EDIT

Майкл Миор предложил следующее (из комментариев)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;
23 голосов
/ 27 мая 2009

Если таблица InnoDB, см. http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html - она ​​использует непротиворечивое чтение (режим без блокировки) для SELECTs, которые не указывают FOR UPDATE или LOCK IN SHARE MODE, если установлена ​​опция innodb_locks_unsafe_for_binlog и уровень изоляции транзакции не установлен в SERIALIZABLE. Таким образом, для строк, считанных из выбранной таблицы, блокировки не установлены ".

16 голосов
/ 27 мая 2009

Использование

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

Версия 5.0 Документы здесь .

Версия 5.1 Документы здесь .

13 голосов
/ 27 мая 2009

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

MyISAM использует блокировки таблиц для достижения очень высокой скорости чтения, но если вы ожидаете оператора UPDATE, то последующие SELECTS будут стоять в очереди за UPDATE.

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

2 голосов
/ 28 мая 2009

В зависимости от типа таблицы блокировка будет выполняться по-разному, но также будет учитываться значение SELECT. Для таблиц MyISAM простая таблица SELECT count (*) FROM не должна блокировать таблицу, поскольку она обращается к метаданным для получения количества записей. Innodb будет занимать больше времени, поскольку для подсчета записей ему нужно захватить таблицу в моментальном снимке, но это не должно вызывать блокировку.

Вы должны по крайней мере установить concurrent_insert в 1 (по умолчанию). Затем, если в файле данных нет «пробелов» для заполнения таблицы, вставки будут добавлены к файлу, и SELECT и INSERT могут происходить одновременно с таблицами MyISAM. Обратите внимание, что удаление записи создает «пробел» в файле данных, который попытается заполнить будущими вставками и обновлениями.

Если вы редко удаляете записи, вы можете установить concurrent_insert равным 2, и вставки всегда будут добавляться в конец файла данных. Тогда выбор и вставка могут происходить одновременно, но ваш файл данных никогда не станет меньше, независимо от того, сколько записей вы удаляете (кроме всех записей).

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

0 голосов
/ 07 июня 2013

Другой способ включить грязное чтение в MySQL - добавить подсказку: LOCK IN SHARE MODE

SELECT * FROM TABLE_NAME LOCK IN SHARE MODE; 
0 голосов
/ 28 мая 2009

SELECT обычно не делают никакой блокировки, которая вам нужна для таблиц InnoDB. Уровень изоляции транзакции по умолчанию означает, что выбор не блокирует вещи.

Конечно, споры все еще случаются.

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

С это ссылка:

Если вы явно заблокировали таблицу с LOCK TABLES, вы можете запросить ЧИТАЙТЕ МЕСТНУЮ блокировку, а не ЧИТАЙТЕ заблокировать, чтобы включить другие сеансы выполнять одновременные вставки в то время как вы заблокировать стол.

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