уровни изоляции и блокировки Inno db
Я читаю руководство о транзакциях innodb, но все же, есть много неясных вещей для меня. Например, я не совсем понимаю следующее поведение:
-- client 1 -- client 2
mysql> create table simple (col int)
engine=innodb;
mysql> insert into simple values(1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into simple values(2);
Query OK, 1 row affected (0.00 sec)
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update simple set col=10 where col=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update simple set col=42 where col=2;
-- blocks
теперь ждет последняя команда обновления (в клиенте 2). Я ожидал бы, что команда будет выполнена, потому что я бы предположил, что только строка 1 заблокирована. Поведение такое же, даже если вторая команда в клиенте 2 insert
. Может ли кто-нибудь описать фон блокировки за этим примером (где и почему замки)?
3 ответов
InnoDB устанавливает определенные типы замков следующим образом.
выбрать ... FROM-это согласованное чтение, чтение моментального снимка базы данных и установка блокировок, если уровень изоляции транзакции не установлен в SERIALIZABLE. Для СЕРИАЛИЗУЕМОГО уровня поиск устанавливает общие блокировки следующего ключа для встречаемых записей индекса.
выбрать ... ОТ... LOCK IN SHARE MODE устанавливает общие блокировки следующего ключа для всех записей индекса поиск встречи.
для индексных записей поисковых встреч выберите ... ОТ... Для обновления блокирует другие сеансы от выполнения SELECT ... ОТ... Блокировка в режиме SHARE или от чтения на определенных уровнях изоляции транзакций. Последовательные чтения будут игнорировать любые блокировки, установленные для записей, существующих в представлении чтения.
обновление ... ГДЕ... устанавливает эксклюзивную блокировку следующего ключа для каждой записи, с которой сталкивается поиск.
удалить ОТ... ГДЕ... устанавливает эксклюзивную блокировку следующего ключа для каждой записи, с которой сталкивается поиск.
INSERT устанавливает эксклюзивную блокировку вставленной строки. Эта блокировка является блокировкой индексной записи, а не блокировкой следующего ключа (то есть нет блокировки зазора) и не препятствует вставке других сеансов в зазор перед вставленной строкой.
InnoDB имеет несколько типов блокировок уровня записи:
блокировка записи: это блокировка на записи индексов.
Gap lock: это блокировка зазора между индексными записями или блокировка зазора до первой или после последней индексной записи.
Next-key lock: это комбинация блокировки записи на записи индекса и блокировки зазора на зазоре перед записью индекса.
Посмотреть Подробнее :
ypercube имеет это право. В частности, без уникального индекса, который используется в условии, он заблокирует больше, чем одна строка.
чтобы увидеть поведение, которое вы ожидаете, измените создание таблицы на это:
create table simple (col int unique) ENGINE=InnoDB;
уникальный индекс на col
поле позволит заблокировать только затронутую строку.
" для индексных записей поисковых встреч выберите ... ОТ... Для обновления блокирует другие сеансы от выполнения SELECT ... ОТ... Блокировка в режиме SHARE или от чтения на определенных уровнях изоляции транзакций. Последовательные чтения будут игнорировать любые блокировки, установленные для записей, существующих в представлении чтения"
каковы те определенные блокировки, которые могут быть применены с помощью select for update, чтобы другие сеансы не могли читать заблокированную запись?