Mysql锁(翻译)
内容主要是对mysql文档的翻译。
1. shared(s) 共享锁
2. exclusive(x) 排它锁
innodb的s锁和x锁是行级锁。
事务T1获得s锁,事务T2仍然可以获得s锁。
事务T1获得x锁,事务T2只有在T1释放该锁后,才能获得x锁。
共享锁的作用是,就像在说“我现在要读这条数据,你们不要改它”。
排它锁就是:“我现在要改这条数据,所以你们不要改,也不要读”
3. Intention Locks
意向锁
innodb支持允许行级锁和表级锁共存的多粒度锁。为了使多粒度锁能实用,使用了一种被称为意向锁的附加类型的锁。意向锁是innodb中的表级锁,它表明一个事务为了表中的某一行后续需要哪种类型的锁(共享或排他)。在innodb中使用了2种意向锁(假定事务T请求了表 t 某种类型的锁):
intention shared(IS): 事务T想要对表 t 中的某些行加s锁。
intention exclusive(IX):事务T想要对表 t 中的某些行加x锁。
例如:select ... lock in share mode 加IS锁,而 select ... for update 加IX锁。
意向锁的规则如下:
在一个事务获取表t中某行的s锁之前,它必须先获取一个表t的IS锁或者更强的锁。
在一个事务获取表t中某行的x锁之前,它必须先获取一个表t的IX锁。

一个锁会赋予给请求事务,如果请求的锁与事务现有的锁兼容。事务会等待直到现有的冲突锁被释放。如果一个请求的锁和现有的锁冲突了,导致无法获取锁,这会导致死锁,出错。
因此,意向锁不会阻塞任何事,除了对整张表的请求(lock table ... write)。IX和IS锁的主要作用是告诉别人,有人正在锁住某行记录,或者将要锁住表中的某行。
4. Record Locks 记录锁
一个记录锁是一条索引记录的锁。例如, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 阻止其他事务插入,更新或删除t.c1值等于10的行。
记录锁通常锁住索引记录,即使一张表并没有定义索引。针对这样的情况,innodb创建一种隐藏的聚集索引,并且使用这种索引来锁住记录。看Section 14.8.9, “Clustered and Secondary Indexes”。
5. Gap Locks 间隙锁
间隙锁是索引记录的间隙上的锁,或者是第一行之前的间隙,或者最后一行之后的间隙。例如,
select c1 from t where c1 between 10 and 20 for update; 阻止其他事务插入t.c1等于15的行,不管表中是否存在t.c1等于15,因为在该范围内,所有现有值之间的间隙都被锁定。
一个间隙可能包含0个、一个、多个索引值。
间隙锁是一种性能和并发之间的折中,使用在某些事务隔离级别上。
对于通过使用唯一索引查询某一行并锁住该行的语句,并不需要间隙锁。(查询条件中只包含“多列唯一索引”的部分列,这种情况仍然会产生间隙锁)。例如,id列有唯一索引,下面的语句只对id等于100的行用了索引记录锁,不会影响其他事务在这个间隙内插入行。
select * from child where id = 100;
如果id列没有索引,或者有非唯一索引,上面的语句会锁住间隙。
这里值得注意的是:不同的事务可以在一个间隙上持有冲突锁。例如,事务A可以持有一个共享间隙锁(gap S-lock),同时事务B在相同的间隙上持有排他间隙锁(gap X-lock)。允许冲突的间隙锁的原因是:如果一条记录根据索引被清除了,不同事务在这条记录上的间隙锁必须合并。
innodb中的间隙锁是“单纯禁止的”,意味着他门只堵塞其他事务往间隙内插入数据。他门不会阻止其他事务从相同的间隙获取锁。因此,gap X-lock和gap S-lock的效果是一样的。
间隙锁可以显式地被关闭。这会发生,当你设置事务隔离级别为读已提交或者使innodb_locks_unsafe_for_binlog (现在已经废弃)系统变量生效。在这些情况下,间隙锁对于查询,索引扫描没有启用,只在外键约束检查和重复键检查时起作用。
设置事务隔离级别为读已提交,或者使innodb_locks_unsafe_for_binlog系统变量生效也有其他作用。当MySQL计算where表达式后,非匹配行上的记录锁会被释放。对于update语句,innodb做了一次“半一致性读”,所以它返回最新的提交版本给mysql,所以mysql能决定行是否匹配update的where条件。
6. Next-Key Locks
Next-Key 锁是两种锁的结合:索引记录上的记录锁和在索引记录前的间隙上的间隙锁。
innodb 采用行级锁,导致当它查询或扫描一个表索引时,它会在遇到的的索引记录上加共享或排他锁。因此,
行级锁实际上是索引记录锁。一条索引记录上的next-key锁也会影响索引记录前的“间隙”。那就是,next-key锁是索引记录锁
加上索引记录前的间隙的间隙锁。如果一个会话拥有索引记录R上的共享锁或排他锁,另一个会话不能立刻在R索引顺序前面的间隙中插入新的索引记录。
假定一个索引包含值10, 11, 13, 和 20。这个索引可能的next-key锁覆盖下面的间隔,一个圆括号表示开区间,方括号表示闭区间:
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)
最后一个间隔,next-key锁锁住索引中最大值和大于索引中任何值的“上界”的间隙。这个上界不是真实的索引记录,所以,效果上,这个next-key锁只锁住了包含最大索引值的间隙。
默认地,innodb 运行在可重复读事务隔离级别,设置 innodb_locks_unsafe_for_binlog 系统变量为disabled。在这种情况下,innodb 在查询和索引扫描时使用next-key锁,以阻止幻影行。
7. Insert Intention Locks
插入意向锁
插入意向锁是一种间隙锁,插入操作加的在插入行前的间隙锁。锁以这种方式提示插入的意向,导致不同事务插入相同索引间隙不需要等待其他人,如果他们不是插入间隙中的相同位置。
假定,存在值4和7的索引记录,分别有两个事务试图插入5和6,每个事务在获得已插入行的排他锁之前,分别用插入意向锁锁住4和7之间的间隙,但是不会阻塞其他人因为插入的行是不冲突的。
下面的例子展示一个事务在获得插入记录的排他锁之前,会获取插入意向锁。示例中涉及2个客户端,A和B。
A创建一张包含2条索引记录(90和102)的表,然后开始一个事务,用大于100的id在索引记录上加排他锁。排他锁包含记录102钱的间隙锁。
mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
mysql> INSERT INTO child (id) values (90),(102);
mysql> START TRANSACTION;
mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE;
B开始一个事务,往间隙中插入一条记录。事务在等待获得排他锁时,加上插入意向锁。
mysql> START TRANSACTION;
mysql> INSERT INTO child (id) VALUES (101);
8. AUTO-INC Locks
自动增长锁
AUTO-INC锁是一种特别的表级锁,当事务向表中插入自动增长的列时需要获取这种锁。最简单的情形,如果一个事务在向表中插入值,任何其他事务向该表插入数据时必须
等待,这样第一个事务中插入的行才能收到连续的主键值。
innodb_autoinc_lock_mode配置项,控制着自增长锁的算法。它允许你选择如何在可预测的自增值的序列和插入操作的最大并发之间折中。
更多信息,查看 Section 14.8.1.5, “AUTO_INCREMENT Handling in InnoDB”.
Mysql锁(翻译)的更多相关文章
- MySQL锁这块石头似乎没有我想的那么重
前言 前言为本人写这篇文章的牢骚,建议跳过不看. 之前好几次都想好好的学习MySQL中的锁,但是找了几篇文章,看了一些锁的类型有那么多种,一时间也没看懂是什么意思,于是跟自己说先放松下自己,便从书 ...
- mysql锁
锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数 ...
- Mysql锁初步
存储引擎 要了解mysql的锁,就要先从存储引擎说起. 常用存储引擎列表如下图所示: 最常使用的两种存储引擎: Myisam是Mysql的默认存储引擎.当create创建新表时,未指定新表的存储引擎时 ...
- mysql锁表机制及相关优化
(该文章为方便自己查阅,也希望对大家有所帮助,转载于互联网) 1. 锁机制 当前MySQL支持 ISAM, MyISAM, MEMORY (HEAP) 类型表的表级锁,BDB 表支持页级锁,InnoD ...
- MySQL锁系列3 MDL锁
http://www.cnblogs.com/xpchild/p/3790139.html MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...
- 01 MySQL锁概述
锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O 等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有 ...
- Mysql锁机制介绍
Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...
- MySQL锁等待分析【2】
MySQL锁等待分析[1]中对锁等待的分析是一步一步来的.虽然最后是分析出来了,可是用时是比较长的:理清各个表之间的关系后,得到如下SQL语句,方便以后使用 select block_trx.trx_ ...
- MySQL锁与MVCC
--MySQL锁与MVCC --------------------2014/06/29 myisam表锁比较简单,这里主要讨论一下innodb的锁相关问题. innodb相比oracle锁机制简单许 ...
- MySQL锁总结
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/78 MySQL 锁基础 参考了何登成老师文章的结构MySQL 加 ...
随机推荐
- 树莓派 无屏幕 安装Ubuntu系统 无头安装 无显示器 用网线
能看到此篇博客的人说明都尝试失败了,会发现内存卡刷入Ubuntu后,无法通过ssh操作树莓派.是因为官方的ubuntu系统在初次运行时需要设定一些东西,类似windows第一次启动也需要设置那样,如果 ...
- _itemmod_extract_enchant
comment 备注 entry 物品ID CanExtract 1 - 可提取随机FM 0 - 不可提取随机FM,当CanExtract = 1 且有随机FM效果时,随机FM效果会被提取 CanEn ...
- 阿里云CentOS Linux服务器上搭建邮件服务器遇到的问题
参考文章: 阿里云CentOS Linux服务器上用postfix搭建邮件服务器 Linux系统下邮件服务器的搭建(Postfix+Dovecot) 本来想自己搭建邮件服务器,但是看到一篇资料表示阿里 ...
- js code
//在页面增加一个放置图标的区块 if(!document.getElementById('_span_jiucuo')) document.write("<span id='_spa ...
- Oracle 12C ORA-65096: 公用用户名或角色名无效
先说基本用法: 先按11G之前进行 conn / as sysdba; create user test identifed by test; ORA-65096: 公用用户名或角色名无效. 查官方文 ...
- JavaScript 局部刷新
JavaScript局部刷新具体代码展示如下 1. #tabList代表需要刷新的元素的对象 2. 第二个#tabList 如果后面有第三个元素,那么后面需要加>*符号,如果不加,容易造成C ...
- typeScript入门基础 (2): 数据 类型, 函数定义
1. number , boolean, string, null, undefind 枚举, any, array数组, 元祖, 2...枚举,需要的注意点, 下一个图,就是为什么yello ...
- P481tabtenn0
编程环境为Qt Creator 4.0.3 (Community) tabtenn0.h #ifndef TABTENN0_H #define TABTENN0_H #include <stri ...
- Java用FutureTask实现又返回值的线程
要实现有返回值的多线程,具体代码如下: package thread; import java.util.concurrent.Callable; import java.util.concurren ...
- Redis持久化AOF和RDB对比
RDB持久化 AOF持久化 全量备份,一次保存整个数据库 增量备份,一次保存一个修改数据库的命令 保存的间隔较长 保存的间隔默认一秒 数据还原速度快 数据还原速度一般 save会阻塞,但bgsave或 ...