mysql间隙锁怎么解锁 mysql间隙锁与mvcc( 二 )


意向锁,为了避免DML在执行时,加的行锁与表锁的冲突,在innodb中引入了意向锁,使得表锁不用检查每行数据是否加锁 , 使用意向锁来减少表锁的检查 。意向锁分为,意向共享锁is由语句select ... lock in share mode添加 。意向排他锁ix,由insert,update , delete,select 。。。for update 添加 。
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_lock;
行级锁,每次操作锁住对应的行数据,锁定粒度最?。⑸逋坏母怕首罡撸⒎⒍磷罡? ,应用在innodb存储引擎中 。
innodb的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁,对于行级锁,主要分为以下三类:
1、行锁或者叫record lock记录锁,锁定单个行记录的锁,防止其他事物对次行进行update和delete操作,在RC,RR隔离级别下都支持 。
2、间隙锁Gap lock,锁定索引记录间隙(不含该记录) , 确保索引记录间隙不变,防止其他事物在这个间隙进行insert操作,产生幻读 , 在RR隔离级别下都支持 。
3、临键锁Next-key-lock,行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap,在RR隔离级别下支持 。
innodb实现了以下两种类型的行锁
1、共享锁 S: 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁 。
2、排他锁 X: 允许获取排他锁的事务更新数据 , 阻止其他事务获得相同数据集的共享锁和排他锁 。
insert 语句 排他锁 自动添加的
update语句 排他锁 自动添加
delete 语句 排他锁 自动添加
select 正常查询语句 不加锁。。。
select。。。lock in share mode 共享锁 需要手动在select 之后加lock in share mode
select。。。for update 排他锁 需要手动在select之后添加for update
默认情况下,innodb在repeatable read事务隔离级别运行 , innodb使用next-key锁进行搜索和索引扫描,以防止幻读 。
间隙锁唯一目的是防止其它事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用的间隙锁 。
深入理解MySQL的间隙锁因为行锁只能锁住行,但是新插入记录这个动作 , 要更新的是记录之间的“间隙” 。为了解决幻读问题,InnoDB 只好引入新的锁,也就是间隙锁 (Gap Lock) 。
间隙锁,锁的就是两个值之间的空隙 , 不允许两个值之间再插一个值 。
比如初始化插入了 6 个记录 , 这就产生了 7 个间隙 。分别是 (-∞,0)、(0,5)、(5,10)、(10,15)、(15,20)、(20, 25)、(25, +supremum),间隙锁都是开区间
和行锁不一样的是,跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作 。间隙锁之间都不存在冲突关系 。
缺点:可能会导致同样的语句锁住更大的范围,影响了并发度 。
间隙锁和行锁合称 next-key lock , 每个 next-key lock 是前开后闭区间 。如果用 select * from t for update 要把整个表所有记录锁起来,就形成了 7 个 next-key lock , 分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum] 。
和间隙锁的最大区别是,next-key lock 为前开后闭区间 , 这样所有的next-key lock就可以把所有记录锁起来 。
加锁规则里面,包含了两个“原则”、两个“优化”和一个“bug”
MySQL白菜教程(Level 10 - 意向锁&记录锁&间隙锁)意向锁(Intention Locks; table-level lock)
意向锁是一种特殊的表级锁,意向锁是为了让 InnoDB 多粒度的锁能共存而设计的 。取得行的共享锁和排他锁之前需要先取得表的意向共享锁(IS)和意向排他锁(IX),意向共享锁和意向排他锁都是系统自动添加和自动释放的,整个过程无需人工干预

推荐阅读