innodb lock

Intro

  • RR 隔离级别 `For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key locks to block insertions by other sessions into the gaps covered by the range. For information about gap locks and next-key locks, see Section 15.7.1, “InnoDB Locking”.

  • lock 是不是一定上在cluster index 上?sql 使用了的辅助索引查询,该如何上锁?

a) 锁一定是锁 cluster index 值的, 但是锁的范围肯定是使用的索引的scan 范围。而不是 where 条件过滤后。
b) 通过二级索引更新记录,首先会在WHERE条件使用到的二级索引上加Next-key类型的X锁,以防止查找记录期间的其它插入/删除记录,然后通过二级索引找到primary key并在primary key上加Record类型的X锁

  • rr 隔离级别中,非 unique 会使用 next key locks (如果关掉 gap 锁的话,gap 锁会失效)。 gap 锁是不是只会影响 insert ? 不影响 update、delete ?
实验1:
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
); 

insert into test (title) values ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g');

在 transaction A 中执行 : select * from test where id in (2, 5, 8);
在 transaction B 中执行: update test set title = 'cc' where id = 3 ; delete from test where id = 3 均可以, 证明了 gap 锁只会影响 insert, 不会影响 update 和 delete。

实验二:
采用辅助索引 for update, 然后 update 已有项使之落在 gap 锁内。测试一下,是否会被组织
CREATE TABLE `test2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) NOT NULL,
  index idx_age (`age`),
  PRIMARY KEY (`id`)
); 

insert into test2 (age) values (1), (2), (3), (4), (5), (6), (7);

Transcation A: select * from test2 where age in (2, 5, 7) for update;
Transcation B: insert into test2 (age) values (3) ; 不会被锁住, 新增记录的 id 为 8。  update  test2 set age =2 where id = 8 会被锁住。
考虑到 test2 中 id 时自增,且没有空洞。不是一个很典型的 gap lock 使用场景。 

实验3:
基于 实验2。
drop test2;
CREATE TABLE `test2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) NOT NULL,
  index idx_age (`age`),
  PRIMARY KEY (`id`)
); 

insert into test2 (age) values (1), (2), (3);
begin; insert into test2 (age) values (4), (5); rollback; commit;
insert into test2 (age) values (6), (7);

Transaction A:  select * from test2 where age in (1, 3, 7) for update;
Transcation B: insert into test2 (id, age) values (4, 4) 会锁住。

  • 如果看锁日志? select * from sys.innodb_lock_waits 是空的
  • gap 锁的锁定范围和 supremum 的关系是啥?
  • 意向锁的意义是啥?
兼容 行锁和 表锁。 不然上个表锁岂不是要挨个遍历行,以确保没有行锁
  • 目前了解的锁相关的知识,都是在研习 幻读 时学习的。除了 幻读 以外,还有什么场景会用到锁?
  • innodb 中的间隙锁 和 记录锁会不会自动升级为表锁?
  • 为什么 innodb 会有死锁,和 2PL 有什么关系?
原文地址:https://www.cnblogs.com/tmortred/p/12913123.html