【译文】MySQL InnoDB 使用的锁分析
InnoDB 使用的 锁类型
共享锁和排它锁
意向锁
记录锁
间隙锁
Next-key 锁
插入意向锁
AUTO-INC 锁
共享锁和排他锁
InnoDB实现了俩个标准的行级锁,共享锁和排它锁。
共享锁允许持有者读取一行
排它锁允许持有者更新或者删除一行
如果一个事物T1在 r 行持有一把共享锁,则来自于不同的事物T2在 r 行上的锁请求将按照如下方法处理:
T2请求共享锁可以立即被授权,因此T1和T2都持有了在 r 行上的共享锁
T2请求排它锁不可以立即被授权。
如果一个事物T1在 r 行持有一把排它锁,则来自与不同事物T2在r上的任何锁请求将不会立即被授权。
意向锁
InnoDB支持多粒度锁:指允许表级锁和行级锁共存。为了实现在多粒度级别上锁,额外的锁类型(意向锁)被使用。意向锁是一个表级锁,它表明未来在那张表上会有哪一种锁类型(排他或者共享)被事物请求。
InnoDB有俩种类型的意向锁(假设事物将来会在某张表t上请求锁):意向共享锁,意向排他锁。
意向共享锁:指事物意图在表t上的某些行上加S锁
意向排它锁:指事物意图在表t上的某些行上加X锁
意向锁协议描述如下:
事物在表t上的一行上加S锁之前,他必须获取IS锁或者在t上更强的锁(指表级锁)
事物在表t上的一行上加X锁之前,他必须获取IX锁
上述锁规则协议可以方便的概括如下的兼容性矩阵:
X |
IX |
S |
IS |
|
|---|---|---|---|---|
X |
Conflict | Conflict | Conflict | Conflict |
IX |
Conflict | Compatible | Conflict | Compatible |
S |
Conflict | Conflict | Compatible | Compatible |
IS |
Conflict | Compatible | Compatible | Compatible |
注:意向锁是MySQL自己自动处理,为了解决表级锁和行级锁的冲突,即提早检测锁冲突。
S、X、IS、IX锁兼容性矩阵为什么是这样子呢?
1、意向锁之间彼此不会冲突,因为它们都只是“有意”,而不是真干,所以是可以兼容的。在加行锁之前,会使用意向锁判断是否冲突;2、IX和X的关系等同于X和X之间的关系,为什么呢?因为事务获得了IX锁,接下来就有权利获取X锁,这样就会出现两个事务都获取X锁的情况,这和我们已知的X锁和X锁之间互斥是矛盾的;3、S和IS、X和IS、IX和IS也可以由此推导出来。
一个锁被授予一个事物,是在该锁与事物已获取的锁兼容的时候,而不是与现有锁冲突的时候。事物等待直到冲突的锁被释放。如果一个锁请求与现有的锁冲突,并且因为死锁不能被授予,一个错误会发生,MySQL自己决定哪个事物回滚。
因此意向锁不阻塞任何事物,除了全表锁请求。IX锁和IS锁是用来表明某个人或者事物正在持有锁或者将要持有锁。
记录锁
一个记录锁是在索引记录上的锁,仅锁住一行。例如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 阻止任何其他事物插入、更新、删除c1=10的行,前提是c1有索引。
记录锁锁住的只是记录的索引“记录”,及时一个表没有定义任何索引,InnoDB也会默认创建一个聚簇索引,并用来加锁。
不符合where条件的记录锁会被释放。
间隙锁
间隙锁是指锁住索引记录之间的空隙(并不锁住索引记录,即开区间),或者明确指定索引记录的第一个和最后一个,例如:SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止任何其他事物的插入、更新和删除
Gap可以仅有一个值,多个值或者为空。
Gap锁是在性能和并发度上权衡的结果,并被某些事物隔离级别使用。
Gap锁在一些使用唯一索引的来检索唯一行的语句中是没有必要的,因为索引的结果是唯一的,没有间隙,不会妨碍其他会话(事物)插入记录。注,那些语句中包含唯一索引和二级索引的仍然适用Gap锁。
值得注意的是,在不同事物中,锁冲突可以发生在同一个间隙里,例如一个事物A持有一把共享GAP锁在Gap间隙中,同时事物B持有一把排他的Gap锁,俩个Gap属于同一个。
注,举一个例子,假设数据库存在id为1,2,3,5,7;事物1:select * from student where id between 3 and 9 for update; 事物2:select * from student where id = 8; 俩个事物共享(7-9)这个间隙锁,但互不影响。
冲突Gap被允许的原因是如果一个记录从索引中被清除了,不同事物在这个记录上的Gap锁必须合并。
注:上述情况未实验成功,首先是不太明白其意思,其次是如果删除索引记录,意味着加X锁,然而这个锁的排他性已经是冲突了,并不能验证成功。如果有人直销烦请告知,不胜感激!
Gap锁在InnoDB中是纯抑制作用,意思是Gap锁仅阻止其他事物插入这个gap间隙,他们不阻止不同的事物在相同的gap上获取gap锁。因此,GapX锁和GapS锁有相同的效果。
Gap锁可以被禁用,通过设置RC隔离级别,或者启用 innodb_locks_unsafe_for_binlog系统变量(当前已标记为了弃用),此时,在检索和扫描的时候Gap锁被禁用,且仅被用作外键检查和重复值检测。
注:当用唯一索引时,三种方法可能产生间隙锁:
1. 唯一检索值不存在,此时会在索引中寻找“最小区间”加间隙锁;
2. between and 条件筛选确定索引间隙加锁;
3. 检索值和比较操作符,例如大于小于检索值(此时符合的记录也会加记录锁,不仅仅是间隙锁)
Next-key Locks
Next-key锁是记录锁和Gap锁的结合。
InnoDB 执行行级锁,因此,当检索或扫描表索引时,他设置S或者X锁到遇到的索引记录上。因此,行级锁实际上是记录锁,一个索引记录上的next-key锁,同样影响索引记录之前的gap。就是说next-key锁是一个记录锁,加上一个gap(记录之前)锁。
假设索引里面有10,11,13,20。则可能的next-key锁是:
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)
默认地,InnoDB提供的事物隔离级别是RR,此时InnoDB使用的是next-key锁,在检索和扫描的时候。以阻止幻读。next-key在使用唯一索引时会降级为记录锁,提高并发度。
插入意向锁(一种特殊的gap锁):
插入意向锁是当插入操作执行时,设置的一种特殊的gap类型锁。这个lock标志一种插入行为:如果每个事物插入gap中的位置不一样时在多事物插入相同的gap情况不需要互相等待。这主要是提高并发插入效率。
AUTO-INC锁
该锁类型是一种特殊的表级锁,在事物插入自动增长字段时使用。如果一个事物插入列值(自动增长列)到表中,任何其他的事物必须等待,因此插入的字段才会是连续的值。
innodb_autoinc_lock_mode配置选项,控制自动增长锁使用的算法,它允许你选择插入操作时,如何来权衡可预测的自动增长值和最大并发度
注:
排它锁和共享锁是指锁的性质,意图锁是意图。
记录锁和Gap锁是锁的范围,这就会出现是在一定的范围加特定性质的锁的问题。
【译文】MySQL InnoDB 使用的锁分析的更多相关文章
- MySql InnoDB中的锁研究
# MySql InnoDB中的锁研究 ## 1.InnoDB中有哪些锁### 1. 共享和排他(独占)锁(Shared and Exclusive Locks) InnoDB实现标准的行级锁定,其中 ...
- Mysql InnoDB 数据更新导致锁表
一.数据表结构 CREATE TABLE `jx_attach` ( `attach_id` int(11) NOT NULL AUTO_INCREMENT, `feed_id` int(11) DE ...
- MySQL/InnoDB中,对于锁的认识
MySQL/InnoDB的加锁,一直是一个面试中常问的话题.例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?我在工作过程中,也会经常用到,乐观锁,排它锁,等.于是今天就对 ...
- mysql innodb 行级锁升级
创建数据表test,表定义如下所示: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NO ...
- mysql innodb存储引擎 锁 事务
以下内容翻译自mysql5.6官方手册. InnoDB是一种通用存储引擎,可平衡高可靠性和高性能.在MySQL 5.6中,InnoDB是默认的MySQL存储引擎.除非已经配置了不同的默认存储引擎, ...
- mysql InnoDB 的行锁
表的引擎类型必须为InnoDB才可以进行此操作. 相关链接:http://www.cnblogs.com/CyLee/p/5579672.html 共享锁:单独运行前两句,然后新建一个会话使用第三句. ...
- [转]关于MYSQL Innodb 锁行还是锁表
关于mysql的锁行还是锁表,这个问题,今天算是有了一点头绪,mysql 中 innodb是锁行的,但是项目中居然出现了死锁,锁表的情况.为什么呢?先看一下这篇文章. 目时由于业务逻辑的需要,必须对数 ...
- 从一个死锁看mysql innodb的锁机制
背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的insert操 作和delete操作发生了死锁.简单介绍下数据库的情况(因为涉及到 ...
- Mysql InnoDB行锁实现方式(转)
Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...
随机推荐
- 微信小程序、微信公众号、H5之间相互跳转
转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息 ...
- vue基于d2-admin的RBAC权限管理解决方案
前两篇关于vue权限路由文章的填坑,说了一堆理论,是时候操作一波了. vue权限路由实现方式总结 vue权限路由实现方式总结二 选择d2-admin是因为element-ui的相关开源项目里,d2-a ...
- rabbitmq-channel方法介绍
先介绍rabbmitmq的几个方法: // 声明一个队列 -// queue 队列名称 // durable 为true时server重启队列不会消失 (是否持久化) // exclusive 队列是 ...
- Mapped Statements collection does not contain value for 问题的解决
在做SSM项目的时候,遇到MyBatis抛出的一个异常: Mapped Statements collection does not contain value for org.lyk.vo.mapp ...
- xmpp实现的即时通讯聊天(二)
参考网址:http://www.jianshu.com/p/8894a5a71b70 借图描述原理: 三.注册.登陆.聊天功能的实现 故事板如下: 四个类如下: 不喜多言,直接上Demo: Login ...
- hdu 1043 八数码问题
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 高并发第十一弹:J.U.C -AQS(AbstractQueuedSynchronizer) 组件:Lock,ReentrantLock,ReentrantReadWriteLock,StampedLock
既然说到J.U.C 的AQS(AbstractQueuedSynchronizer) 不说 Lock 是不可能的.不过实话来说,一般 JKD8 以后我一般都不用Lock了.毕竟sychronize ...
- Messenger与AIDL的异同
Messenger与AIDL的异同 最近做项目需要使用进程间通信,大家知道应用层的进程间通信无非Broadcast,Activity,Service,Content Provider四大组件.Broa ...
- R中字符串操作
简介 Stringr中包含3个主要的函数族 字符操作 空格处理 模式匹配 常用函数 在平常的数据分析工作中,经常要用到如下的函数 函数 操作 str_length() 获取字符串长度 str_sub( ...
- 微信小程序“满月”:尝鲜之后你还用过它吗?
距离 2017 年 1 月 9 日微信小程序上线,整整过去了一个月时间.和互联网时代每天出现的众多新鲜事物相似,小程序甫一诞生,立即占据了各大科技媒体网站头屏并引起社交圈的兴奋讨论.由于背靠微信,纷纷 ...