Правила Mysql Gap-lock / Next-key Locks - PullRequest
       17

Правила Mysql Gap-lock / Next-key Locks

0 голосов
/ 19 сентября 2018

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

-- isolation level is Repeatable Read
-- create the table
create table t (id int primary key auto_increment, COL1 int, key idx_a(COL1));
insert into t (COL1) values(5), (10), (11), (13), (20);
select * from t;
----   ----
 id  |  COL1
----   ----
 1   |  5
 2   |  10
 3   |  11
 4   |  13
 5   |  20

-- in transaction 1
select * from t where COL1 = 13 for update;
-- in transaction 2
insert into t (COL1) values(10); -- success
insert into t (COL1) values(11); -- blocks
insert into t (COL1) values(12); -- blocks
.
.
insert into t (COL1) values(19); -- blocks
insert into t (COL1) values(20); -- success
-- in transaction 3
update t set COL1 = 11 where COL1 = 10; -- success
update t set COL1 = 12 where COL1 = 10; -- blocks
.
.
update t set COL1 = 20 where COL1 = 10; -- blocks
update t set a = 21 where a = 10; -- success

Так что кажется:

  1. INSERT заблокирован для COL1 со значением в [11, 20) (С 11 по 20, исключая 20)

  2. ОБНОВЛЕНИЕ заблокировано для COL1 со значением в (11, 20] (с 11 по 20, без 11)

Мне интересно, почему MySQL ведет себя таким образом? И каково правило в целом для такого рода блокировок?

Ответы [ 2 ]

0 голосов
/ 04 августа 2019
select * from t where COL1 = 13 for update; 

это предложение sql заблокирует диапазон:

((11,3), (13,4)]
((13,4), (20,5)]

,

insert into t (COL1) values(10); -- success because (10, 6) not in the gap range.

insert into t (COL1) values(11); -- block   because (11, 7) in the gap range.

insert into t (COL1) values(12); -- block   because (12, 8) in the gap range.

insert into t (COL1) values(19); -- block   because (19, 9) in the gap range.

insert into t (COL1) values(20); -- success because (20, 10) not in the gap range.

update t set COL1 = 11 where COL1 = 10; --success because (11,2) not in the gap range.

update t set COL1 = 12 where COL1 = 10; -- blocks because (12,2) in the gap range.

update t set COL1 = 20 where COL1 = 10; -- blocks because (20,2) in the gap range.

update t set COL1 = 21 where COL1 = 10; -- success because (21,2) not in the gap range. 
0 голосов
/ 26 декабря 2018

В MySQL 5.7 InnoDB REPEATABLE READ
Поскольку COL1 имеет не-unque-индекс,
select * from t where COL1 = 13 for update;
Оператор блокирует запись кластерного индекса B + Tree, где id = 4, также блокируетиндекс COL1 B + Tree, где запись имеет COL1 = 10, и блокирует индекс COL1 B + Tree от (k = 11, id = 3) до (k = 20, id = 5) с блокировкой пробела. insert into t (COL1) values(10); equals to : insert into t (id, COL1) values(6,10); gap lock insert into t (COL1) values(11); equals to : insert into t (id, COL1) values(7,11); gap lock insert into t (COL1) values(12); equals to : insert into t (id, COL1) values(8,12); gap lock insert into t (COL1) values(19); gap lock insert into t (COL1) values(20); equals to : insert into t (id, COL1) values(9,20);

Но посмотрите это условие:
CREATE TABLE `t` ( `id` int(11) NOT NULL, `k` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_k` (`k`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8<br> insert into t values(2,2),(6,6); , затем вставьте:
1, insert into t values (1,2); success 2, insert into t values (3,2); block

3, insert into t values (5,6); block 4, insert into t values (7,6); success , если они все могут вставить, где эти значения расположены в дереве k'B +?enter image description here

, чтобы вы могли видеть, что (k = 2, id = 1) можно вставить, поскольку оно не в промежутке, также значение (k = 6, id = 7), (k = 2, id = 3) и (k = 6, id = 5) невозможно вставить, потому что они находятся в промежутке.

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