InnoDB锁类型和使用「译」

InnoDB锁类型

InnoDB引擎使用了八种类型的锁,他们分别是:

  • 共享排他锁(Shared and Exclusive Locks)
  • 意向锁(Intention Locks)
  • 记录锁(Record Locks)
  • 间隙锁(Gap Locks)
  • 临键锁 (Next-Key Locks)
  • 插入意图锁(Insert Intention Locks)
  • 自增锁(AUTO-INC Locks)
  • 空间锁和预测锁(Predicate Locks for Spatial Indexes)

共享排他锁(Shared and Exclusive Locks)

InnoDB 实现了标准的行级锁并且他有两种锁的类型,共享锁(S)和排它锁(X):

  • 共享锁允许持有锁的事物读取一行数据
  • 排它锁允许持有锁的事物删除或者更新一行数据

如果事物T1持有r行共享锁(S),那么事物T2希望对r行上锁的处理如下:

  • T2请求一个S锁,会立即准许。结果,T1和T2两个都会持有S锁。
  • T2请求一个X锁,不会立即准许。(猜测可能会等待)

如果事物T1对r行持有排它锁(X),另一个事物T2的请求则不能够被立即准许持有r行任何一种类型的锁。相反,事物T2不得不等待事物T1释放r行锁。

意向锁(Intention Locks)

InnoDB支持多粒度锁,允许表锁和行锁共存。例如,就像一个表级锁/写( LOCK TABLES ... WRITE)也会带有一个排它锁(X)[释义:排它锁属于行级]。为了实现多力度级别锁,InnoDB使用了意向锁(Intention Locks)。意向锁是表级别的锁,它表明事务稍后对表中的行需要哪种类型的锁(共享或独占)。意向锁有两种类型:

  • 意向共享锁(IS)表明一个事物打算在表的单个行设置共享锁。
  • 意向排它锁(IX)表明一个事物打算在表的单个行设置排它锁。

例如,执行SELECT ... LOCK IN SHARE MODE的时候设置一个IS锁,和执行 SELECT ... FOR UPDATE的时候设置IX锁。

这个意向锁的协议如下:
一个事物能够在表中获取行级共享锁之前,它必须首先在一个表中获得一个IS锁或者更强类型的锁。
一个事物能够在表中获取行级排它锁之前,它必须首先在一个表中获得一个IX锁。

表级别锁类型的兼容性总结如下表所示:

排它锁 意向排它锁 共享锁 意向共享锁
排它锁 x x x x
意向排它锁 x y x y
共享锁 x x y y
意向共享锁 x y y y

如果一个事物请求锁(A)与已存在的锁(B)兼容,则该事物可以得到锁(A);但是,如果不兼容则该事物不会得到锁(A)。事物(A)会一直等待直到锁(B)被释放为止。如果锁(A)请求与已存在锁(B)冲突,则该请求将不能够得到锁(A),因为它可能引发死锁或错误。

除了全表请求以外意向锁不会被阻塞(例如:LOCK TABLES ... WRITE),意向锁最主要的目的是显示某人锁住一行数据或者打算锁住表中的一行数据。

在InnoDB引擎显示和监控输出中意向锁的事物数据如下所示:

TABLE LOCK table `test`.`t` trx id 10080 lock mode IX

记录锁(Record Locks)

记录锁是索引记录上的锁。例如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;预防任何事物从t.c1 = 10.的行插入,更新,和删除额操作。

记录锁总是锁定索引记录,即使表中没有定义索引。对于这种情况,InnoDB 创建了隐式的聚簇索引并使用它来锁定记录。参考:聚簇索引和二级索引

在InnoDB引擎的显示和监控输出中记录锁的事物数据如下所示:

RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t` 
trx id 10078 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 8000000a; asc     ;;
1: len 6; hex 00000000274f; asc     'O;;
2: len 7; hex b60000019d0110; asc        ;;

间隙锁(Gap Locks)

间隙锁是指在索引范围之间加锁,或者是在第一条索引记录之前或者是最后一条索引记录之后的间隙进行加锁。例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;防止其他事物能够从t.c1列插入值为15的数据,不论列中是否已经存在这样的记录值,因为该范围内所有已经存在的值都已被锁定。

间隙可能跨越单个索引,多个索引,甚至是空索引。

隙锁是权衡了性能和并发能力的一个折中选择,在某些隔离级别中使用了间隙锁。

使用唯一索引搜索唯一行时,不需要使用间隙锁。(这并不包括在查找条件中,条件列只是多列唯一索引中的一部分时;此时,间隙锁定会发生)。例如,如果id列有一个惟一的索引,下面的语句只对id值为100的行使用索引记录锁,其他会话是否在前面的空格中插入行并不重要:

SELECT * FROM child WHERE id = 100;

如果id不是索引,或者不是一个唯一索引,则这条语句就会锁住之前的间隙。

在这里值得注意的是,不同的事物可以在间隙上持有冲突锁。例如:事物A在间隙上持有一个共享间隙锁 (gap S-lock) ,同时事物B在相同的间隙上也持有一个排它锁(gap X-lock) 。允许间隙锁冲突的原因是,如果从索引中清除一条记录,则在不同事物中持有的间隙锁记录必须合并。

间隙锁在InnoDB中“完全被抑制的”,这意味着它们的唯一目的是阻止其它事物插入此间隙。间隙锁可以共存。一个事物所采取的间隙锁并不能够阻止其他事物采取相同间隙的间隙锁。共享间隙锁和排它间隙锁是相同。它们之间是不冲突的,并且执行相同的功能。

如果改变事物隔离级别为READ COMMITTED或者启用系统变量innodb_locks_unsafe_for_binlog就可以明确的禁用间隙锁。在这种情况下,对搜索和索引扫描禁用间隙锁,只用于外键约束检查和重复键检查。

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

临键锁 (Next-Key Locks)

未完待续

插入意图锁 (Insert Intention Locks)

未完待续

自增锁 (AUTO-INC Locks)

未完待续

空间锁和预测锁(Predicate Locks for Spatial Indexes)

未完待续

声明

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

推荐阅读更多精彩内容