mysql innodb锁

共享和独占锁

InnoDB实现标准的行级锁定,其中有两种类型的锁,共享(S)锁和独占(X)锁。
共享(S)锁允许持有锁的事务读取行。
独占(X)锁允许持有锁的事务更新或删除行。
如果事务T1在行r上保持共享(S)锁,则来自某个不同事务T2的对行r的锁的请求按如下方式处理:
可以立即授予T2对S锁的请求。
结果,T1和T2都在r上保持S锁定。
T2的X锁定请求不能立即授予。
如果事务T1在行r上保持独占(X)锁定,则不能立即授予来自某个不同事务T2的对r上任一类型的锁的请求。
相反,事务T2必须等待事务T1释放其对行r的锁定。

意向锁

InnoDB支持多种粒度锁定,允许行锁和表锁共存。例如,LOCK TABLES ... WRITE等语句在指定的表上采用独占锁(X锁)。为了实现多个粒度级别的锁定,InnoDB使用意向锁。意图锁是表级锁,它指示事务稍后对表中的行所需的锁(共享或独占)类型。意向锁有两种类型:
意向共享锁(IS)表示事务打算在表中的各个行上设置共享锁。
意向排他锁(IX)表示事务打算在表中的各个行上设置独占锁。
例如,SELECT ... FOR SHARE设置IS锁定,SELECT ... FOR UPDATE设置IX锁定。
意向锁定协议如下:
在事务可以获取表中某行的共享锁之前,它必须首先在表上获取IS锁或更强。
在事务可以获取表中某行的独占锁之前,它必须首先获取表上的IX锁。
表级锁定类型兼容性总结在以下矩阵中。


image.png

如果请求事务与现有锁兼容,则授予锁,但如果它与现有锁冲突则不会。事务等待,直到释放冲突的现有锁。

如果锁定请求与现有锁冲突而无法授予,因为它会导致死锁,则会发生错误。意向锁不会阻止除完整表请求之外的任何内容(例如,LOCK TABLES ... WRITE)。意向锁的主要目的是显示某人正在锁定行,或者要锁定表中的行。

记录锁定

记录锁定是对索引记录的锁定。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;防止任何其他事务插入,更新或删除t.c1的值为10的行。
即使定义了没有索引的表,记录锁也始终锁定索引记录。对于这种情况,InnoDB创建一个隐藏的聚簇索引并使用此索引进行记录锁定。

间隙锁

间隙锁是锁定索引记录之间的间隙,或锁定在第一个之前或最后一个之后索引记录的间隙。
例如,SELECT c1 FROM t WHERE c1 BETWEEN 10和20 FOR UPDATE;
阻止其他事务将值15插入到列t.c1中,无论列中是否已存在任何此类值,因为该范围内所有现有值之间的间隔都被锁定。
间隙可能跨越单个索引值,多个索引值,甚至可能为空。
间隙锁是性能和并发之间权衡的一部分,用于某些事务隔离级别而不是其他级别。
使用唯一索引锁定行以搜索唯一行的语句不需要间隙锁定。
(这不包括搜索条件仅包含多列唯一索引的某些列的情况;在这种情况下,确实会发生间隙锁定。)例如,如果id列具有唯一索引,则以下语句仅使用具有id值100的行的索引记录锁定,其他会话是否在前一个间隙中插入行无关紧要:
SELECT * FROM child WHERE id = 100;

如果id未编入索引或具有非唯一索引,则该语句会锁定前一个间隙。

此处值得注意的是,冲突锁可以在间隙上被不同的事务持有。例如,事务A可以在间隙上保持共享间隙锁定(间隙S锁定),而事务B在同一间隙上保持独占间隙锁定(间隙X锁定)。
允许冲突间隙锁定的原因是,如果从索引中清除记录,则必须合并由不同事务保留在记录上的间隙锁定。

InnoDB中的间隙锁是“纯粹的抑制”,这意味着它们的唯一目的是防止其他事务插入间隙。间隙锁可以共存。一个事务占用的间隙锁定不会阻止另一个事务在同一个间隙上进行间隙锁定。共享和独占间隙锁之间没有区别。它们彼此不冲突,它们执行相同的功能。

可以明确禁用间隙锁定。如果将事务隔离级别更改为READ COMMITTED,则会发生这种情况。在这些情况下,对于搜索和索引扫描禁用间隙锁定,并且仅用于外键约束检查和重复键检查。

使用READ COMMITTED隔离级别还有其他影响。MySQL评估WHERE条件后,将释放不匹配行的记录锁。对于UPDATE语句,InnoDB执行“半一致”读取,以便将最新提交的版本返回给MySQL,以便MySQL可以确定该行是否与UPDATE的WHERE条件匹配。

下一键锁

下一键锁定是索引记录上的记录锁定和索引记录之前的间隙上的间隙锁定的组合。
InnoDB以这样的方式执行行级锁定:当它搜索或扫描表索引时,它会在遇到的索引记录上设置共享锁或排它锁。因此,行级锁实际上是索引记录锁。索引记录上的下一键锁定也会影响该索引记录之前的“间隙”。也就是说,下一键锁定是索引记录锁定加上索引记录之前的间隙上的间隙锁定。如果一个会话在索引中的记录R上具有共享或排他锁,则另一个会话不能在索引顺序中的R之前的间隙中插入新的索引记录。

假设索引包含值10,11,13和20.此索引的可能的下一个键锁定包括以下间隔,其中圆括号表示排除间隔端点,方括号表示包含端点:
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

对于最后一个间隔,下一个键锁定将间隙锁定在索引中最大值之上,而“supremum”伪记录的值高于索引中实际的任何值。supremum不是真正的索引记录,因此,实际上,此下一键锁定仅锁定最大索引值之后的间隙。默认情况下,InnoDB在REPEATABLE READ事务隔离级别运行。
在这种情况下,InnoDB使用下一键锁进行搜索和索引扫描,从而防止幻像行(参见第15.7.4节“幻影行”)

插入意向锁

插入意向锁是在行插入之前由INSERT操作设置的一种间隙锁定。
该锁定表示以这样的方式插入的意图:如果插入到相同索引间隙中的多个事务不插入间隙内的相同位置,则不需要等待彼此。
假设存在值为4和7的索引记录。分别尝试插入值5和6的单独事务,在获取插入行上的排它锁之前,每个锁定4和7之间的间隙和插入意图锁,
但是不要互相阻塞因为行是非冲突的。
以下示例演示了在获取插入记录的独占锁之前采用插入意图锁定的事务。
该示例涉及两个客户端,A和B.
客户端A创建一个包含两个索引记录(90和102)的表,然后启动一个事务,该事务对ID大于100的索引记录放置独占锁。独占锁包括记录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);

AUTO-INC锁

AUTO-INC锁是由插入到具有AUTO_INCREMENT列的表中的事务所采用的特殊表级锁。
在最简单的情况下,如果一个事务正在向表中插入值,则任何其他事务必须等待对该表执行自己的插入,以便第一个事务插入的行接收连续的主键值。innodb_autoinc_lock_mode配置选项控制用于自动增量锁定的算法。它允许您选择如何在可预测的自动增量值序列和插入操作的最大并发之间进行权衡。

空间索引的谓词锁

InnoDB支持包含空间列的列的空间索引。
要处理涉及空间索引的操作的锁定,下一键锁定不能很好地支持REPEATABLE READ或SERIALIZABLE事务隔离级别。多维数据中没有绝对排序概念,因此不清楚哪个是“下一个”键。

为了支持具有空间索引的表的隔离级别,InnoDB使用谓词锁。空间索引包含最小边界矩形(MBR)值,因此InnoDB通过在用于查询的MBR值上设置谓词锁来强制对索引进行一致读取。
其他事务无法插入或修改与查询条件匹配的行。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容