【译文】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这种行锁实现特点 ...
随机推荐
- 安装 wordpress 出现 抱歉,我不能写入wp-config.php文件
本文告诉大家如何安装 wordpress ,在安装过程出现 抱歉,我不能写入wp-config.php文件如何解决 下载 wordpress China 简体中文 - WordPress 安装 在安装 ...
- C#基础笔记(第十四天)
1.MD5加密 用户在数据库存密码需要进行再加密,这样一个过程叫MD5加密只要涉及到存用户的密码一定要用MD5加密MD5密码一般都是16进制的把一个密码转换成16进制的过程就叫MD5加密把字符串加密成 ...
- Java常见对象之String
String类的概述 String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现.字符串是常量,一旦被赋值,就不能被改变. String ...
- spring-boot集成PageHelper和通用Mapper
前提条件:已经集成mybatis 代码生成步骤: 添加依赖 <dependency> <groupId>tk.mybatis</groupId> <artif ...
- Tomcat启动慢原因之一 At least one JAR was scanned for TLDs yet contained no TLDs
Tomcat启动时提示: 信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging f ...
- jquery 给iframe里的元素添加事件
$("#iframeId").on("load", function(event){//判断 iframe是否加载完成 这一步很重要 $("#divI ...
- 自己编写jQuery插件 之 无缝滚动
一. 效果图 二. Html骨架结构 <div class="box"> <ul> <li>1</li> <li>2&l ...
- android studio 加载libs
eclipse 项目转 android studio libs 不能加载 导致不能导入 记录下:libs 放在和src 同路径 dependencies:增加 compile files('libs ...
- atitit.js 与c# java交互html5化的原理与总结.doc
atitit.js 与c# java交互html5化的原理与总结.doc 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参数个数1 1.3. 事件监听2 2. sen ...
- solidity 语法学习
基于 cryptozombies.io ZombieFactory pragma solidity ^0.4.19; contract ZombieFactory { // 事件, web3.js 可 ...