mysql 退化range锁_MySQL-锁总结

锁机制用于管理对共享资源的并发访问。

lock和latch

在数据库中,lock和Latch都称为锁,但是两者意义不同。

latch称为闩锁(shuang suo),其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差。在InnoDB存储引擎中,latch又分为mutex互斥锁 和 rwLock读写锁。其目的是为了保证并发线程操作临界资源的正确性。通常没有死锁的检测机制。

lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或者rollback后进行释放。有死锁检测机制。

e87c76920db1be7b6a82aec8065b438d.png

通过show engine innodb mutex可以查看InnoDB存储引擎的中latch,具体字段详情如下表:

04539de2c8c0d393135dabb84ceaf7aa.png

锁的类型

有几个索引,需要分别向索引加锁。

共享锁、排他锁

InnoDB存储引擎实现了如下两种标准的行级锁:

共享锁(S Lock):允许事务读一行数据

排他锁(X Lock):允许事务删除 或 更新一行数据

如果一个事务T1已经获取了行r的共享锁,那么另外的事务T2可以立即获得行r的共享锁。因为读取并不会改变行的数据,所以可以多个事务同时获取共享锁,称这种情况为锁兼容。但若有其他的事务T3想获得行R的排他锁,则其必须等待事务T1、T2释放行r上面的共享锁,称这种情况为锁不兼容。下面显示了共享锁和排他锁的兼容性:

f442b2163e03e8e9c5c2b64d8149bab6.png

从表6-3可以看出X锁与任何锁都不兼容,而S锁仅和S锁兼容。S锁和X锁都是行锁,兼容是指对同一行记录锁的兼容情况。

普通 select 语句默认不加锁,而CUD操作默认加排他锁。

记录锁

Record Lock,仅锁定一行记录(如共享锁、排他锁)

记录锁总是会去锁定索引记录,如果表在建立的时候,没有设置任何一个索引,那么InnoDB会使用隐式的主键来进行锁定。

查询条件的列是唯一索引的情况下,临建锁退化为记录锁

间隙锁

Gap Lock,锁定一个范围,但不包含记录本身。

关闭间隙锁的2种方式:

(1)将事务隔离级别变为read committed

(2)将参数innodb_locks_unsafe_for_binlog设置为1

在上述配置下,除了外键和唯一性检查依然需要间隙锁,其余情况仅适用行锁进行锁定。

临键锁

Next-Key Lock,等于记录锁 + 临键锁,锁定一个范围,并且锁定记录本身。主要是阻止多个事务将记录插入到同一个范围内,从而避免幻读。

假如一个索引有10、11、13、20这四个值,那么该索引可能被锁定的区间为:

0e408db4aa93aba57538847ba8b17b8a.png

若事务T1已经通过临键锁锁定了如下范围:

d4948a8507f29ed2033a1925507b4d5f.png

当插入新的记录12时,则锁定的范围变成:

26757645821e3960f26c1f9ca5766b0d.png

当查询的索引是唯一索引的时候,InnoDB会将临键锁优化成记录锁,从而提高并发。这时候,将不再由间隙锁避免幻读的问题,但是试验了下,即使优化成记录锁,也不会有幻读的问题,其实是因为MVCC,在可重复读的情况下,SELECT操作只会查找行版本号小于当前事务版本号的记录,其他事务(事务开启时间比当前事务晚)新插入的记录版本号不满足条件,就不会查出来。

对于辅助索引,当执行类似select * from z where b = 3 for update;加锁语句时,会加上临键锁,并且下一个键值的范围也会加上间隙锁。

值得注意的是,对于唯一键值的锁定,由临键锁优化为记录锁,仅存在于查询所有的唯一索引。若唯一索引由多列组成,而查询仅是查找多个唯一索引中的一个,那么查询其实是range类型查询,而不是point类型查询,故InnoDB存储引擎还是继续使用临键锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值