Innodb锁的类型

行锁(record lock)

行锁总是对索引上锁,如果某个表没有定义索引,mysql就会使用默认创建的聚集索引,行锁有S锁和X锁两种类型。

共享锁和排它锁

Innodb锁有两种类型:共享锁(S lock)和排它锁(X lock)

  • 不同事务可以同时对同一行记录加S锁
  • 如果一个事务对某一行记录加X锁,其他事务就不能加S锁或者X锁,从而导致锁等待

使用sqlSELECT ... LOCK IN SHARE MODE可以对一行记录加S锁,sql SELECT ... FOR UPDATE则是加X锁

意向锁(intention lock)

Innodb为了支持多粒度的加锁,允许行锁和表锁同时存在。插入意向锁即是一种表锁,在事务对某一行或者多行加锁之前,必须对这张表加入意向锁(或更强的锁如X锁)。插入意向锁分为:

  • intention shared lock (IS):表明事务对于这张表的记录有插入S锁的意向
  • intention exclusive lock (IX):表明事务对于这张表的记录有插入X锁的意向

插入意向锁和其他表锁兼容性如下:

X IX S IS
X Conflict Conflict Conflict
IX Conflict Compatible Conflict
S Conflict Conflict Compatible
IS Conflict Compatible Compatible

对表加S锁或者X锁可以参考:https://dev.mysql.com/doc/refman/5.7/en/lock-tables.html

间隙锁(gap lock)

间隙锁锁住一个间隙以防止插入。假设索引列有(a,b,c)三个值,如果对b加锁,那么也会同时对(a,b)和(b,c)这两个间隙加锁。其他事务无法插入索引值在这两个间隙之间的记录(即a<索引值<b或者b<索引值<c都无法插入)。但是,间隙锁有一个例外:

  • 如果索引列是唯一索引,那么只会锁住这条记录(只加行锁),而不会锁住间隙。
  • 对于联合索引且是唯一索引,如果where条件只包括联合索引的一部分,那么依然会加间隙锁。

对于间隙锁来说,S锁或者X锁没有区别,它们也不会相互冲突。假设索引列有(a,b,c,d)四个值,事务A对b加X锁,也会同时对(a,b)和(b,c)这两个间隙加X锁。其他事务B可以同时对c加X锁,也会同时对(b,c)和(c,d)这两个间隙加X锁。可以看到两个事务都可以对(b,c)这个间隙加X锁,但是不会引起冲突。

注意,如果将数据库隔离级别改为READ COMMITTED或者开启系统变量innodb_locks_unsafe_for_binlog,那么间隙锁就会被关闭。

next-key lock

next-key lock实际上就是行锁+这条记录前面的gap lock的统称。假设有索引值10, 11, 13, 和20,那么可能的next-key lock包括:

(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

在REPEATABLE READ隔离级别下,InnoDB使用next-key lock主要是防止幻像问题(phantom problem)的产生。

幻想问题指的是一个事务中,两次执行同一个sql可能返回不同数据的现象。这违反了事务的隔离性。设表t有1,2,5三个值。事务A执行以下sql

select * from t where a>2 for update

如果事务没有提交,在没有next-key lock的情况下其他事务B又插入了4这个值并提交,那么A事务再次执行上面的sql就会返回a=4这个值。

插入意向锁(Insert Intention Lock)

插入意向锁指的是事务在对一个gap插入之前会对这个gap加插入意向锁。只要不同事务对于同一个gap插入的位置不同,那么就可以对同一个gap同时加插入意向锁。设有某列有索引值2,6,只要两个事务插入位置不同(如事务A插入3,事务B插入4),那么就可以同时插入。

自增锁(AUTO-INC Lock)

自增锁是一种特殊的表锁。一般说来,为了实现列的自增,不同事务对自增列的插入都会导致锁等待。不过后面mysql对于自增锁做了大量优化,提供了不同算法以实现性能和数据一致的平衡。具体可以参考:https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html

Innodb加锁分析

详细参考:mysql InnoDB加锁分析

Innodb锁等待排查

目前Innodb提供的锁等待排查命令有下面几个:

SHOW FULL PROCESSLIST ;
SHOW ENGINE INNODB STATUS ;
#更为详细
select * from information_schema.INNODB_TRX;
select * from information_schema.INNODB_LOCKS;
select * from information_schema.INNODB_LOCK_WAITS;

通常我使用如下sql来获取必要的信息:

select l.*, t.trx_state,t.trx_weight,t.trx_query,w.* from information_schema.INNODB_TRX t left join information_schema.INNODB_LOCKS l
on t.trx_id=l.lock_trx_id left join information_schema.INNODB_LOCK_WAITS w
on t.trx_id=w.requesting_trx_id;

排查方式可以参考:https://dev.mysql.com/doc/refman/5.7/en/innodb-information-schema-examples.html

Innodb一致性非锁定读(consistent nonblocking read)

前面一个章节讲的是锁定读以保证更新插入数据的一致性,mysql同时也提供不加锁的方式读取数据。mysql使用多版本并发控制(MVCC)来读取数据,如果事务A对某一行正在执行update或delete操作,那么事务B不会读取正在更新的这一行,而是会去读取这行的一个快照数据。



该实现是通过undo段完成,因为undo段用来事务的回滚,因此本身没有额外的开销。

不同的事务隔离级别下,读取的快照版本也不相同

  • READ COMMITTED级别下,一致性非锁定读总是读取被锁定行的最新一份快照数据。所以在这个隔离级别下,同一个事务多次读取同一条记录,返回的结果可能不同,因为存在其他事务提交对这一行更新的可能。
  • REPEATABLE READ级别下,一致性非锁定读总是读取被锁定行事物开始时的行数据版本。同一个事务多次读取同一条记录返回相同的结果。

Innodb锁的类型的更多相关文章

  1. InnoDB 锁的类型

    一.全局锁 mysql> flush table with read lock; FTWRL 会对整个实例加只读锁.会阻塞所有线程读以外的所有操作.查看线程状态 State: Waiting f ...

  2. innodb 锁分裂继承与迁移

    innodb行锁简介 行锁类型 LOCK_S:共享锁 LOCK_X: 排他锁 GAP类型 LOCK_GAP:只锁间隙 LOCK_REC_NO_GAP:只锁记录 LOCK_ORDINARY: 锁记录和记 ...

  3. InnoDB锁机制分析

    InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工作机制.通过 ...

  4. Innodb锁机制:Next-Key Lock 浅谈

    数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S).排他锁(X).意向共享(IS).意向排他(IX).为了提供更好的并发,Inn ...

  5. [转载] 数据库分析手记 —— InnoDB锁机制分析

    作者:倪煜 InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工 ...

  6. Innodb锁机制:Next-Key Lock 浅谈(转)

    http://www.cnblogs.com/zhoujinyi/p/3435982.html 数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类 ...

  7. MySQL · 特性分析 · innodb 锁分裂继承与迁移

    http://mysql.taobao.org/monthly/2016/06/01/ innodb行锁简介 行锁类型 LOCK_S:共享锁 LOCK_X: 排他锁 GAP类型 LOCK_GAP:只锁 ...

  8. Innodb 锁系列2 事务锁

    上一篇介绍了Innodb的同步机制锁:Innodb锁系列1 这一篇介绍一下Innodb的事务锁,只所以称为事务锁,是因为Innodb为实现事务的ACID特性,而添加的表锁或者行级锁. 这一部分分两篇来 ...

  9. MySQL- InnoDB锁机制

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...

随机推荐

  1. HDOJ 5008 Boring String Problem

    后缀数组+RMQ+二分 后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa Boring String Problem Time Limit: 6000 ...

  2. 重写MPAndroidChart显示标记

    MPAndroidChart是实现图表功能的优秀控件, 能够完毕大多数绘制需求. 对于改动第三方库而言, 优秀的架构是继承开发, 而不是把源代码拆分出去. MP在显示标记控件(MarkView)时, ...

  3. Android面试精华

    SIM卡的EF文件有什么作用? SIM卡里的全部文件按树来组织: 主文件MF(Master File)--主文件仅仅有文件头,里面存放着整个SIM卡的控制和管理信息 专用文件DF(Dedicated ...

  4. Thinkphp 无法使用-&gt;order() 排序的两种解决的方法!

    使用ThinkPHP,却发现无法使用->order($order)来排序. $order = " info.date2 desc "; 非常遗憾的是这样写结果order却变成 ...

  5. [JZOJ3385] [NOIP2013模拟] 黑魔法师之门 解题报告(并查集)

    Description 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Vi ...

  6. [NOI2002] Savage 解题报告(扩展欧几里得)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1407 Description 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些 ...

  7. 机器学习(一) K-means聚类

    聚类算法K-means是硬聚类算法,是目标函数聚类算法的代表.K-means算法以欧式距离作为相似度测度,它是求对应某一初始聚类中心向量V最优分类,使得评价指标J最小.算法采用误差平方和准则函数作为聚 ...

  8. MyEclipse for mac 快捷键

    原文出处:http://blog.csdn.net/ray_seu/article/details/17384463 一直比较欣赏myeclipse的快捷键,网上搜索了一圈,发现windows平台下面 ...

  9. caffe(9) caffe例子

    为了程序的简洁,在caffe中是不带练习数据的,因此需要自己去下载.但在caffe根目录下的data文件夹里,作者已经为我们编写好了下载数据的脚本文件,我们只需要联网,运行这些脚本文件就行了. 注意: ...

  10. Codeforces#441 Div.2 四小题

    Codeforces#441 Div.2 四小题 链接 A. Trip For Meal 小熊维尼喜欢吃蜂蜜.他每天要在朋友家享用N次蜂蜜 , 朋友A到B家的距离是 a ,A到C家的距离是b ,B到C ...