Innodb锁的类型
Innodb锁的类型
行锁(record lock)
行锁总是对索引上锁,如果某个表没有定义索引,mysql就会使用默认创建的聚集索引,行锁有S锁和X锁两种类型。
共享锁和排它锁
Innodb锁有两种类型:共享锁(S lock)和排它锁(X lock)
- 不同事务可以同时对同一行记录加S锁
- 如果一个事务对某一行记录加X锁,其他事务就不能加S锁或者X锁,从而导致锁等待
使用sql
SELECT ... LOCK IN SHARE MODE
可以对一行记录加S锁,sqlSELECT ... 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锁的类型的更多相关文章
- InnoDB 锁的类型
一.全局锁 mysql> flush table with read lock; FTWRL 会对整个实例加只读锁.会阻塞所有线程读以外的所有操作.查看线程状态 State: Waiting f ...
- innodb 锁分裂继承与迁移
innodb行锁简介 行锁类型 LOCK_S:共享锁 LOCK_X: 排他锁 GAP类型 LOCK_GAP:只锁间隙 LOCK_REC_NO_GAP:只锁记录 LOCK_ORDINARY: 锁记录和记 ...
- InnoDB锁机制分析
InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工作机制.通过 ...
- Innodb锁机制:Next-Key Lock 浅谈
数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S).排他锁(X).意向共享(IS).意向排他(IX).为了提供更好的并发,Inn ...
- [转载] 数据库分析手记 —— InnoDB锁机制分析
作者:倪煜 InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工 ...
- Innodb锁机制:Next-Key Lock 浅谈(转)
http://www.cnblogs.com/zhoujinyi/p/3435982.html 数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类 ...
- MySQL · 特性分析 · innodb 锁分裂继承与迁移
http://mysql.taobao.org/monthly/2016/06/01/ innodb行锁简介 行锁类型 LOCK_S:共享锁 LOCK_X: 排他锁 GAP类型 LOCK_GAP:只锁 ...
- Innodb 锁系列2 事务锁
上一篇介绍了Innodb的同步机制锁:Innodb锁系列1 这一篇介绍一下Innodb的事务锁,只所以称为事务锁,是因为Innodb为实现事务的ACID特性,而添加的表锁或者行级锁. 这一部分分两篇来 ...
- MySQL- InnoDB锁机制
InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...
随机推荐
- JVM分代通俗解释
JVM分代通俗解释 学习了:https://www.cnblogs.com/zgghb/p/6428395.html
- OC中的@的作用研究
OC中的@字符用的频率很的高,其主要作用是为了差别于其它语言的keyword和语法 以下我们来研究一下其应用 1.声明类,协议,延展,权限,属性等 @interface声明类 @protocol声明协 ...
- bzoj2127: happiness(双倍经验最小割)
2127: happiness 题目:传送门 题解: 双倍经验美滋滋~ 请看蒟蒻以前写的渣题解...bzoj3894 表示做完自己就最小割了... 代码(直接改的...菜啊): #include< ...
- 安卓开发--scrollview
package com.cnn.scrollviewdemo01; import android.R.integer; import android.annotation.SuppressLint; ...
- LOJ #109. 并查集
内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论 1 测试数据 题目描述 这是一道模板题. 维护一个 nnn 点 ...
- net实现压缩功能
public static class Compressor { public static byte[] Compress(byte[] data) { using (MemoryStream ou ...
- SSD-tensorflow-3 重新训练模型(vgg16)
一.修改pascalvoc_2007.py 生成自己的tfrecord文件后,修改训练数据shape——打开datasets文件夹中的pascalvoc_2007.py文件,根据自己训练数据修改:NU ...
- [Bug]Python3.x SyntaxError: 'ascii' codec can't decode byte 0xe4 in position
安装arch后就没再用python了 昨天管服务器的大佬在跑贝叶斯分类器的时候发现正确率有问题 我赶紧去做优化,然后就有这样的报错 Python 3.6.4 (default, Jan 5 2018, ...
- sql查询 按照规定的顺序返回结果集。
DECODE函数 oracle 独有,功能强大.相当于 if else if IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN RETURN(翻译值2) ..... ...
- CSU 1249 竞争性酶抑制剂和同工酶
1249: 竞争性酶抑制剂和同工酶 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 109 Solved: 49 Description 人体内很多化学 ...