MySQL 间隙锁 gap lock

参考:间隙锁 gap lock - 简书

概念:

        对于键值在条件范围内但并不存在的记录叫做“间隙”,InnoDB也会对这种 “间隙” 加锁,这种锁机制叫做 “间隙锁”。

产生原因:

        间隙锁的出现主要集中在同一个事务中先deleteinsert的情况下, 当我们通过一个条件去删除一条已有记录时:

  • 如果参数在数据库中存在,那么这个时候产生的是普通行锁,锁住这个记录并删除, 然后释放锁。
  • 如果这条记录不存在,问题就来了:数据库会扫描索引,发现这个记录不存在,这时的delete语句获取到的就是一个间隙锁。然后数据库会向左扫描到第一个比给定条件小的值,向右扫描扫描到第一个比给定条件大的值。 最后以此为界构建一个区间, 锁住整个区间内的数据, 一个特别容易导致死锁的间隙锁诞生了。

前提:

  • 间隙锁是在可重复读隔离级别下才会生效的。所以,你如果把隔离级别设置为读已提交的话,就没有间隙锁了。
  • 检索条件必须有普通索引(没有索引的话,MySQL会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

不在主键唯一索引上用间隙锁是因为这两种记录都是唯一的,不存在间隙,但是在范围查询的时候还是会用到间隙锁


作用:

        为了防止出现幻读(读到之前不存在的新增记录,或之前存在的记录被其他并发事务删除,导致前后结果集不一致),但会把锁定范围扩大。

危害:

        会造成在锁定时无法插入锁定键值范围内的任何数据(包括不存在的键值),在某些场景下可能会对性能造成很大影响。

是否开启设置:
        在数据库参数中, 控制间隙锁的参数是:innodb_locks_unsafe_for_binlog,这个参数默认值是OFF, 也就是启用间隙锁, 他是一个bool值, 当值为true时表示disable间隙锁。
        那为了防止间隙锁是不是直接将innodb_locaks_unsafe_for_binlog设置为true就可以了呢? 不一定!而且这个参数会影响到主从复制及灾难恢复, 这个方法还尚待商量。

补充:

        除了间隙锁以外,还有一种next-key锁,next-key锁 = 记录锁 + 间隙锁。即锁定一个范围,并且锁定记录本身,InnoDB默认加锁方式是 next-key 锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值