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 使用的锁分析的更多相关文章

  1. MySql InnoDB中的锁研究

    # MySql InnoDB中的锁研究 ## 1.InnoDB中有哪些锁### 1. 共享和排他(独占)锁(Shared and Exclusive Locks) InnoDB实现标准的行级锁定,其中 ...

  2. Mysql InnoDB 数据更新导致锁表

    一.数据表结构 CREATE TABLE `jx_attach` ( `attach_id` int(11) NOT NULL AUTO_INCREMENT, `feed_id` int(11) DE ...

  3. MySQL/InnoDB中,对于锁的认识

    MySQL/InnoDB的加锁,一直是一个面试中常问的话题.例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?我在工作过程中,也会经常用到,乐观锁,排它锁,等.于是今天就对 ...

  4. mysql innodb 行级锁升级

    创建数据表test,表定义如下所示: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NO ...

  5. mysql innodb存储引擎 锁 事务

    以下内容翻译自mysql5.6官方手册. InnoDB是一种通用存储引擎,可平衡高可靠性和高性能.在MySQL 5.6中,InnoDB是默认的MySQL存储引擎.除非已经配置了不同的默认存​​储引擎, ...

  6. mysql InnoDB 的行锁

    表的引擎类型必须为InnoDB才可以进行此操作. 相关链接:http://www.cnblogs.com/CyLee/p/5579672.html 共享锁:单独运行前两句,然后新建一个会话使用第三句. ...

  7. [转]关于MYSQL Innodb 锁行还是锁表

    关于mysql的锁行还是锁表,这个问题,今天算是有了一点头绪,mysql 中 innodb是锁行的,但是项目中居然出现了死锁,锁表的情况.为什么呢?先看一下这篇文章. 目时由于业务逻辑的需要,必须对数 ...

  8. 从一个死锁看mysql innodb的锁机制

    背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的insert操 作和delete操作发生了死锁.简单介绍下数据库的情况(因为涉及到 ...

  9. Mysql InnoDB行锁实现方式(转)

    Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...

随机推荐

  1. idea中maven项目程序包找不到解决办法之一

    首先检查maven配置对不对,包括被settings文件以及资源库的位置,maven版本等. 如果不行的话再进行下面的操作: 第一种方案: 在终端terminal中项目目录下,输入“mvn idea: ...

  2. C# 实现二叉树各种排序

    1. 引言 在实际的项目中,树还是用的比较多的一种,尤其是对于具有层次结构的数据.相信很多人都学过树的遍历,比如先序遍历,后序遍历等,利用递归还是很容易理解的. 今天给大家介绍下二叉树的几种遍历算法, ...

  3. Java并发基础知识你知道多少?

    并发 https://blog.csdn.net/justloveyou_/article/details/53672005 并发的三个特性是什么? 什么是指令重排序? 单线程的指令重排序靠什么保证正 ...

  4. K:有限状态自动机

      有限状态自动机是一种特殊的状态机.它表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型.有限状态自动机分为两种,一种是 确定有限状态自动机(DFA) ,一种是 非确定有限状态自动机(NF ...

  5. jQuery Grid入门指南

    上周需要把一个项目中的普通table改成使用jQuery插件形式的表格,找到了jqgrid这个插件,本以为找个demo,查查api就能解决,没想到还是费了一番的功夫,在这里记录总结一下. 本文实现的内 ...

  6. DDD Quickly - 读书笔记

    读后感:关于领域驱动设计,过去多多少少用到一些.所以,这本精简版看起来很快,很多概念很熟悉,它帮助我把散乱的知识串起来.最后,Eric Evans谈到一点,本来软件的发展是向着处理复杂的业务逻辑走的, ...

  7. ECMAScript 5和ECMAScript6的新特性以及浏览器支持情况

    ECMAScript简介: 它是一种由Ecma国际(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范,javascript在它基础上经行了自己的封装.但通常来说,术语ECMAScript和java ...

  8. Integer和new Integer

    Java code   ? 1 2 3 4 5 6 7 8 9 10 public static void main(String[] args) {     Integer i1=10;     I ...

  9. 一起玩转CoordinatorLayout

    作为Material Design风格的重要组件,CoordinatorLayout协调多种组件的联动,实现各种复杂的效果,在实际项目中扮演着越来越重要的角色.本篇博客将由浅到深,带你一起玩转Coor ...

  10. flutter实现(OutlineButton)线框按钮

    在flutter的控件里 常用按钮有:FlatButton,RaisedButton,FloatingActionButton,OutlineButton. FlatButton是扁平的,没有阴影的. ...