mysql - Mysql Gap-lock/Next-key Locks规则

标签 mysql locking

我不确定为什么会发生以下行为。我认为它必须与间隙锁定/下一键锁定有关。文档中提到了它们,但解释并不详细。

-- 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. UPDATE 被锁定为 COL1,值为 (11, 20](11 到 20,不包括 11)

我想知道为什么 MySQL 会这样?这种锁定的一般规则是什么?

最佳答案

在 MySQL 5.7 InnoDB 下可重复读
因为COL1有一个non-unque-index,
select * from t where COL1 = 13 for update;
该语句锁定 cluster-index B+Tree record where id = 4,还锁定 COL1 index B+Tree where the record having COL1=10,并锁定 COL1 index B+Tree from (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+Tree 中的位置? enter image description here

所以可以看到 (k=2, id=1) 可以插入,因为它不在间隙中,也值 (k=6, id=7), (k=2, id=3) and ( k=6, id=5) 不能插入,因为它们在间隙中。

关于mysql - Mysql Gap-lock/Next-key Locks规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52399319/

相关文章:

sql语法问题

php - 在 wordpress 中重写自定义 URL

php - 如何禁用php中的mysql功能

php - codeigniter 加入计数另一个表

python - 使用 python 线程锁和循环导入时的意外行为

C# 线程访问 if block ,其条件返回 false

c# - C# 中的单例线程安全 - 为什么要添加双重检查?

php - 将 HTML 链接转换为 PHP 链接?

Python:来自 `threading` 和 `multiprocessing` 的锁可以互换吗?

sql - 添加没有表锁的新列?