加锁的基本单位为next-key lock = 间隙锁+行锁 无论什么情况下,InnoDB 会往前扫描到第一个不满足条件的行为止。 数据准备# 其中,id 是主键索引(唯一索引),b 是普通索引(非唯一索引),a 是普通的列 唯一索引等值查询# 结论 当查询的记录是存在的,在用「唯一索引进行等值查询」时,next-key lock 会退化成「...
在非主键唯一索引范围查询时,不是覆盖索引的时候,会对相应的范围加前开后闭区间,并且如果存在数据,会对对应的主键加行锁; 在非主键唯一索引范围查询时,如果是覆盖索引时,会对所有的后闭区间对应的主键,加行锁; 在非主键唯一索引加锁时,还是存在 next-key 锁住下一个区间的 bug。 4普通索引 普通索引等值查询,...
因为是等值查询,不需要锁id = 15那条记录,next-key lock 会退化为间隙锁; 最终区间为 (10,15) 的前开后开区间。 使用data_locks 分析一下锁信息: 看下锁的信息X,GAP表示加了间隙锁,其中 LOCK_DATA = 15,表示锁的是 主键索引 id = 15 之前的间隙。 此时在另一个 Session 执行 SQL,答案显而易见,是...
当next-key lock加在某索引上,则该记录和它前面的区间都被锁定。 假设有记录1, 3, 5, 7,现在记录5上加next-key lock,则会锁定区间(3, 5],任何试图插入到这个区间的记录都会阻塞。 注意,由于其效果相当于(3, 5)上的gap lock加5上的record lock,而且gap lock是可重入的,相互不阻塞的(上文讲过),当其...
next-key lock的锁定区间,其主要目的是为了解决幻读。我理解如果是在RR级别下,有next-key lock解决幻读,这样的例子应该是举不出来。可以在RC级别试试,这时候没解决幻读,应该不存在next-key lock了。 在唯一索引上,退化成行锁,是因为可以找到唯一的一条记录,就可以使用Record lock(单个行记录的锁)。注意:如果...
InnoDB 执行行级锁以这种方式 当它搜索或者扫描一个表的索引,它设置共享或者排它锁在Index records。 因此, row-level locks 实际上是 index-record locks. 一个next-key lock 在一个index record 也会影响 那个index record 记录前的gap 也就是说 一个next-key lock 是一个 index-record lock plus a gap...
2. 在RR隔离级别下,更新操作如何使用next-key lock 在RR隔离级别下,当进行更新操作时,如果更新条件是基于索引字段(包括非唯一索引和主键索引),InnoDB会使用next-key lock来锁定相关的索引记录。next-key lock是索引记录上的一个锁定,它锁定一个范围,并且锁定的是索引记录以及索引记录之前的“间隙”。这种锁定方式可...
select * from information_schema.innodb_lock_waits; kill <information_schema.innodb_trx表中trx_mysql_thread_id> 测试结果 测试总结(计算锁定范围) 1.将查询条件分解为区间 2.计算单个分解区间对应的最终锁定区间 1.如果分解区间存在-infinity、+infinity的端点,则无需计算。
Record lock单条索引记录上加锁,record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。
LOCK_MODE = X是前开后闭区间; X,GAP是前开后开区间(间隙锁); X,REC_NOT_GAP行锁。 这个单独介绍,是希望我理解的没有错误,如果大佬看到了,错误之处一定要帮忙指正出来。 主键索引 加锁时,会先给表添加意向锁,IX 或 IS; 加锁是如果是多个范围,是分开加了多个锁,每个范围都有锁;(这个可以实践下 id ...