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. 从Oracle Database 角度来看浪潮天梭K1主机的操作系统选择

    背景: 浪潮天梭k1主机.事实上分好几个类别: K1-950 intel 安腾cpu K1-930 intel 安腾cpu K1-910 intel 安腾cpu K1-800 intel 志强cpu ...

  2. 【Android应用开发技术:基础构建】命令行下的Android应用开发

    作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.co ...

  3. bzoj1055: [HAOI2008]玩具取名(dp)

    1055: [HAOI2008]玩具取名 题目:传送门 简要题意: 就是固定四个字母,给出这四个字母分别可以由哪两个字母组成,然后在给你一个字符串,要求把这个字符串还原成原始的四个字母的其中一个. 题 ...

  4. Dictionaries and tuples

    Dictionaries have a method called items that returns a list of tuples, where each tuple is a key-val ...

  5. 安卓开发--HttpDemo01

    package com.cnn.httpdemo01; import android.app.Activity; import android.content.Intent; import andro ...

  6. kali 2.0 linux中的Nmap的主机探测

    不多说,直接上干货! 如果是第一次接触Nmap,推荐在MSF终端中输入不加任何参数的Nmap命令,以查看其使用方法. 更多,其实, msf > nmap -h [*] exec: nmap -h ...

  7. 使用NiftyModeEffects对话框

    最近看到一篇有关个性对话框的文章,里面介绍了非常酷的动画效果,开源的项目下载来试试,用法很简单. NoftyDialogEffects效果参考:       http://tympanus.net/D ...

  8. PostgreSQL Replication之第七章 理解Linux高可用(5)

    7.5 高可用性是所有冗余 让我们从一个不同的角度看一下前面的混合超市的例子.为了处理大量顾客无需长排队,无需关闭超市,混合超市雇用更多的出纳员以及安装许多(甚至更多)的收银机. 这样,如果一个收银机 ...

  9. SweetAlert的入门

    在做后台管理系统,在用户交互这块(弹窗.提示相关),用了一款还不错的插件SweetAlert(一款原生js提示框,允许自定义,支持设置提示框标题.提示类型.确认取消按钮文本.点击后回调函数等等), 效 ...

  10. Windows 10 计划带来颜文字和Sandbox

    在最新的 Window 10 测试版 Build 18305 中,Windows 10 增加了对颜文字(kaomoji)的支持. Kaomoji 是由日本符号序列组成的面脸部表情的名称.虽然有些人,比 ...