InnoDB 行锁的三种算法及Phantom Problem(读MySQL技术内幕-InnoDB存储引擎)

行锁三种算法:

    Record Lock:单个行记录上的锁

    Gap Lock:间隙锁,锁定一个范围,但不会针对里面的每条记录上锁

    Next-Key Lock:Gap Lock + Record Lock 锁定一个范围,且对记录本身也上锁

 

   Record Lock:锁定的是索引,没有索引的话,锁定的是隐式的主键

   Next-Key Lock:此算法的锁定技术称为:Next-Key Locking

                             对于行的查询都是采用这种锁定算法,若一个索引有10,11,13,20四个值,则锁定的区间分别为:

                             (-∞,10]  (10,11]  (11,13]  (13,20]  (20,+ ∞)

                             还有previous-key locking 技术,它锁定的区间为:

                             (-∞,10)  [10,11)  [11,13)  [13,20)  [20,+ ∞)

                   若事务T1已经通过Next-Key Locking 锁定了如下范围:(10,11]  (11,13]

                   当插入新的记录12时,则锁定的范围变为:(10,11]  (11,12] (12,13]

   当查询的索引含有唯一属性时,InnoDB会对Next-Key Lock进行降级处理,将其降级为Record Lock,即仅锁住索引本身

  demo:

  session1:

# 一:加入X锁
begin ;
select * from t_test_locking where id = 20 for update ;

# 三:查出id为18这条记录
select * from t_test_locking;

# 四:提交
commit ;

session2:

# 二:insert 加入的也是X锁(可以执行完,没有阻塞)
begin ;
insert into t_test_locking (id, name) values (19,190);
commit ;

  分析:session1中的for update是加了X锁的,session2中insert 也是加X锁的。查询用的是Next-Key Lock算法,所以会锁定(18,20]这个区间,则session2中插入id=19应该是阻塞的,事实没有,所以发生了锁的降级。

 

当查询条件为辅助索引时(此时name字段添加了辅助索引):

select * from t_test_locking where name = 70 for update ;

 此时其实添加了三把锁

 一:对于辅助索引,添加了传统的Next-Key Lock ,锁定的范围是(50,70)

 二:因为有主键聚集索引,所以会在id为7的索引上添加Record Lock

 三:InnoDB会对辅助索引的下一个键值添加Gap Lock,范围是(70,100)

 

 

Phantom Problem(幻像问题):

    同一个事务下,连续执行俩次同样的SQL语句可能会导致不同的结果,第二次的SQL语句可能会返回之前不存在的行

    默认隔离级别(REPEATABLE READ)下,InnoDB采用Next-Key Locking 机制避免幻读

    在这篇里面:https://blog.csdn.net/qq_35970057/article/details/108365061

     

 其实就是解释了第七步的原因,默认隔离级别REPEATABLE-READ时,用的是Next-Key Locking算法,锁的不仅仅是这一条记录,将后面的范围也锁住了,所以只有当第二个事务提交了,且第一个事务也提交了后,第一个事务才能看到第二个事务提交后的内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值