уровни изоляции и блокировки inno db - PullRequest
8 голосов
/ 20 февраля 2012

Я читаю руководство по транзакциям 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 ]

9 голосов
/ 24 февраля 2012

InnoDB устанавливает определенные типы блокировок следующим образом.

  • SELECT ... FROM - согласованное чтение, считывание снимка базы данных и установка без блокировок, если уровень изоляции транзакции не равенустановить в SERIALIZABLE.Для уровня SERIALIZABLE поиск устанавливает общие блокировки следующего ключа для записей индекса, с которыми он сталкивается.

  • SELECT ... FROM ... LOCK IN SHARE MODE устанавливает общие блокировки следующего ключа навсе индексные записи встречаются при поиске.

  • Для индексных записей поисковые запросы, SELECT ... FROM ... FOR UPDATE блокирует выполнение других сеансов SELECT ... FROM ... LOCK.В режиме SHARE или из чтения на определенных уровнях изоляции транзакции.Последовательные чтения будут игнорировать любые блокировки, установленные для записей, которые существуют в представлении чтения.

  • UPDATE ... WHERE ... устанавливает эксклюзивную блокировку следующего ключа для каждой записи, с которой встречается поиск.

  • DELETE FROM ... WHERE ... устанавливает эксклюзивную блокировку следующего ключа для каждой записи, с которой сталкивается поиск.

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

InnoDB имеет несколько типов блокировок на уровне записи:

  • Блокировка записи: это блокировка индексной записи.

  • Gap lock: это блокировка промежутка между индексными записями или блокировка промежутка до первой или после последней индексной записи.

  • Блокировка следующей клавиши: это комбинация блокировки записи для индексной записи и блокировки пропуска для пропуска перед индексной записью.

См. Подробнее:

Предотвращение фантомной проблемы с помощью блокировки следующей клавиши

Предотвращение тупика

1 голос
/ 23 февраля 2012

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

Чтобы увидеть ожидаемое поведение, измените создание таблицы на следующее:

create table simple (col int unique) ENGINE=InnoDB;

Уникальный индекс в поле col позволит заблокировать только затронутую строку.

0 голосов
/ 16 июня 2014

"Для записей индекса поисковые запросы, SELECT ... FROM ... FOR UPDATE блокируют другие сеансы от выполнения SELECT ... FROM ... LOCK IN SHARE MODE или от чтения на определенных уровнях изоляции транзакции. Последовательные чтения будут игнорировать любые блокировки, установленные для записей, которые существуют в режиме чтения "

Что это за определенные блокировки, которые можно применить с помощью select для обновления, чтобы другие сеансы не могли прочитать заблокированную запись?

...