Mysql 优化笔记
InnoDB 存储引擎
InnoDB 锁和事务模型
InnoDB 常见的锁类型
-
+
首页
InnoDB 常见的锁类型
参考:[InnoDB Locking](https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html) InnoDB 常见的锁主要有: 1、共享和排它锁(Shared and Exclusive Locks) 2、意向锁(Intention Locks) 3、记录锁(Record Locks) 4、间隙锁(Gap Locks) 5、临键锁(Next-Key Locks) 6、插入意向锁(Insert Intention Locks) 7、自增锁(AUTO-INC Locks) 8、空间索引的谓词锁(Predicate Locks for Spatial Indexes) ## 共享和排它锁 - Shared and Exclusive Locks InnoDB 实现了标准的行级锁,行级锁只有两个类型的锁,共享锁(S)以及排它锁(X),拥有共享锁的事务可以读取数据,拥有排它锁的事务可以更新或者删除数据。 你可以这么理解,如果你用了事务,然后去读取数据,此时,你是共享锁,对你需要读取的数据加了共享锁,而如果你是更新或者删除,则会用排它锁。 我们举个例子,假如事务 1 拥有 A 这行数据的共享锁,此时,事务 2 如果要读取 A 这行数据,那么,事务 2 会立刻被允许,事务 1 和事务 2 都可以读取到这行数据,如果事务 2 要更新或者删除 A 这行数据,那么事务 2 就需要等待,只有事务 1 提交或者回滚后,事务 2 才会被允许。如果事务 1 拥有 A 这行数据的排它锁,那么,无论事务 2 是读取还是更新删除 A 这行数据,都需要等待。 共享和排它锁还是很好理解的,共享锁,可以在多个事务间共享,共同拥有,而排它锁,则只允许一个事务拥有,读取数据并不会导致数据变化,此时,没必要限制别的事务读取,但是更新和删除则会让数据发生变化,此时,无论是更新还是读取都应该等待,否则就错乱了。这是最基本的常识了。 ## 意向锁 - Intention Locks Innodb 支持行锁以及表锁,假设事务 1 请求对 A 表的第 1 行进行读取,即 A 表第 1 行的共享锁,事务 2 请求对 A 表表级的排它锁,此时就需要判断事务 2 是否应该获得锁,由于事务 1 拥有行级共享锁,事务 2 不应该有表级排它锁,这时候,其实需要判断是否有事务拥有 A 表的行级锁,或者表级锁,判断表级锁可能容易,但是判断是否有行级锁,就很痛苦,除非一行行去判断,那么效率将极低,有个办法:如果有事务拥有了 A 表的行级锁,则更新某个标识变量,这样就不用为了判断是否有行级锁而头疼,这就是意向锁,即我要更新删除或者读取某行数据了,就这样子。 意向锁是表级锁,分为意向共享锁(IS)以及意向排它锁(IX),事务在获得行级共享锁前,必然要获得表级共享锁,或者表级排它锁,事务在获得行级拍它锁前,必然要获得表级排它锁。表级锁的兼容如下图: | | 排它锁 | 意向排它锁 | 共享锁 | 意向共享锁 | | :--: | :--: | :--: | :--: | :--: | | 排它锁 | X | X | X | X | | 意向排它锁 | X | √ | X | √ | | 共享锁 | X | X | √ | √ | | 意向共享锁 | X | √ | √ | √ | ## 记录锁 - Record Locks 记录锁,我更愿意叫它索引记录锁,它是给索引记录加锁,它始终给索引记录加锁,如果表没有主键也没有索引,InnoDB 会创建一个隐藏的聚合(聚集)索引,并使用这个索引。 ## 间隙锁 - Gap Locks 间隙锁和记录锁类似,是针对索引记录上一块数据的锁,主要为了解决幻读,间隙可能是单个索引,也可能是多个索引,甚至可能是空,所谓幻读,指的是:同一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行,幻读专指新插入的行,而修改的不算。 假设A表 num 为非唯一索引,int 类型,目前存在 num 为 1、5、10 三条数据,此时事务1更新 num 为 3的数据时,产生间隙锁,间隙锁左开右闭,即产生的间隙锁为(1, 5] ,大于1小于等于5,此时,事务2 插入 num 为 2、3、4、5 的数据时,都会等待锁,如果存在 num 为 1、3、5 的数据,事务1更新num为3的数据时,事务2无法插入 num 为 1、4、5 的数据。 ## 临键锁 - Next-Key Locks 官方的解释是这样的: > A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record 翻译过来大致意思是:临键锁是记录锁和间隙锁的组合,这里的 before the index record 值得深思。 ## 插入意向锁 - Insert Intention Locks 插入意向锁是在插入一条记录行前,由 INSERT 操作产生的一种间隙锁。 该锁用以表示插入意向,当多个事务在同一区间(gap)插入位置不同的多条数据时,事务之间不需要互相等待,插入意向锁不是意向锁,是间隙锁,插入数据时,产生插入意向锁+记录锁。 ## 自增锁 - AUTO-INC Locks 如果主键是自增的,插入数据时,产生自增锁,自增锁是表级锁,自增锁和 `innodb_autoinc_lock_mode` 这个配置有关,具体后面再补充。 ## 空间索引的谓词锁 - Predicate Locks for Spatial Indexes 这个暂时不好理解,以后补充,可参考:[ mysql8中文手册 ](https://blog.csdn.net/michaelrainy/article/details/115249257?spm=1001.2014.3001.5501)
十三
2021年6月4日 11:12
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码