[译] MySQL InnoDB 锁类型介绍

原文地址:https://docs.oracle.com/cd/E17952_01/mysql-5.5-en/innodb-locking.html

本节介绍 InnoDB 的锁类型:

共享和排他锁(Shared and Exclusive Locks)

InnoDB 实现了标准的行级锁,分为两种类型:共享(S)锁排他(X)锁

如果事务T1在行 r 上持有共享(S)锁,则其他事务T2对行 r 的锁的请求按如下方式处理:

  • 可以立即授予T2对S锁的请求。 结果,T1和T2都在r上持有S锁。
  • T2的X锁定请求不能立即授予。

如果事务T1在行r上持有排他(X)锁,则不能立即授予其他事务T2对r上任何类型的锁请求。相反,T2必须等待T1释放其对行r的锁定。

意向锁(Intention Locks)

InnoDB支持多种粒度的锁,允许行锁和表锁共存。 例如 LOCK TABLES ... WRITE
等语句在指定的表上持有排他锁(X 锁)。 InnoDB用意向锁来实现多粒度级别的锁。意向锁是表级锁,表示事务稍后对表中的行进行加相关类型的锁(共享或排他)。意向锁有两种类型:

例如 SELECT ... LOCK IN SHARE MODE 设置IS锁, SELECT ... FOR UPDATE设置IX锁定。

意向锁的规则如下:

  • 事务在获取表中某行的共享锁之前,必须先获取表上的 IS 锁或类似的锁。
  • 事务在获取表中某行的排他锁之前,必须先获取表上的 IX 锁。

下面是表级锁类型兼容性总结:

当前事务现有的锁 / 其他事务的锁请求 X IX S IS
X 冲突 冲突 冲突 冲突
IX 冲突 兼容 冲突 兼容
S 冲突 冲突 兼容 兼容
IS 冲突 兼容 兼容 兼容

如果事务请求的锁与现有锁兼容就授予锁,如果冲突则不会。 事务会一直等到现有的锁释放。如果因为事务请求的锁与现有的锁冲突而无法授予,则可能会导致发生死锁(deadlock)错误。
除全表请求之外,意向锁不会阻塞任何事务(例如 LOCK TABLES ... WRITE)。意向锁的主要目的是表示某人正在锁定行,或将要锁定表中的行。
意向锁的事务数据与 SHOW ENGINE INNODB STATUSInnoDB monitor 输出中的以下内容类似:

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创建了一个隐藏的聚簇索引并使用此索引做记录锁。 请参见 第14.11.2.1节“聚簇和二级索引”

记录锁的事务数据在SHOW ENGINE INNODB STATUS和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; 阻止其他事务将值15插入到列 t.c1 中,无论列中是否存在任何此类值,因为该范围内所有现有值之间的区间都被锁定。

区间可能跨越单个索引值,多个索引值,甚至可能为空。
区间锁是性能和并发之间权衡的一部分,用于某些事务隔离级别而不是其他级别。

使用唯一索引(unique index )锁定行以搜索唯一行的语句不需要区间锁。(这不包括搜索条件仅包括多列唯一索引的一些列的情况; 在这种情况下,确实会发生区间锁定。)例如,如果id列具有唯一索引,则以下语句仅对id值为100的行使用索引记录锁,并且其他会话是否在前一个间隙中插入行无关紧要:

SELECT * FROM child WHERE id = 100;

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

这里还值得注意的是,不同的事务在相同区间上可以存在相互冲突的锁类型。 例如,事务A可以在区间上持有共享区间锁(区间S锁),而事务B在同一区间上持有排他区间锁(区间X锁)。 允许区间锁冲突的原因是,如果从索引中清除记录,则必须合并由不同事务保留在记录上的区间锁。

在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

Next-Key锁是索引记录上的记录锁和索引记录之前的区间上的区间锁的组合。

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

假设索引包含值10,11,13和20。此索引的可能的Next-Key锁定包括以下间隔,其中圆括号表示排除区间端点,方括号表示包含端点:

(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +∞)

对于最后一个区间,Next-Key 锁将区间锁定在索引中最大值之上,而“supremum”伪记录的值高于索引中实际的任何值。supremum不是真正的索引记录,因此,实际上,此Next-Key锁仅锁定最大索引值之后的间隙。

默认情况下,InnoDB 在 REPEATABLE READ (RR) 事务隔离级别运行,并禁用系统变量innodb_locks_unsafe_for_binlog 。在这种情况下,InnoDB 使用 Next-Key 锁进行搜索和索引扫描,从而防止幻像行(参见 Section 14.8.4, “Phantom Rows”)。

Next-Key 锁的事务数据与 SHOW ENGINE INNODB STATUSInnoDB监视器 输出中的以下内容类似:

RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t` 
trx id 10080 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

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        ;;

Insert Intention Locks

待翻译

AUTO-INC Locks

AUTO-INC 锁是由插入到具有 AUTO_INCREMENT 列的表中的事务所采用的特殊表级锁。在最简单的情况下,如果一个事务正在向表中插入值,则任何其他事务必须等待对该表执行自己的插入,以便第一个事务插入的行接收连续的主键值。

可以通过配置项 innodb_autoinc_lock_mode 调整自增锁算法,例如:调整自增序列和插入操作的最大并发。

请参见:Section 14.11.1.5, “AUTO_INCREMENT Handling in InnoDB”.

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

推荐阅读更多精彩内容

  • Mysql概述 数据库是一个易于访问和修改的信息集合。它允许使用事务来确保数据的安全性和一致性,并能快速处理百万条...
    彦帧阅读 13,591评论 10 461
  • MySQL技术内幕:InnoDB存储引擎(第2版) 姜承尧 第1章 MySQL体系结构和存储引擎 >> 在上述例子...
    沉默剑士阅读 7,304评论 0 16
  • 一、概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种...
    忘忧谷主阅读 580评论 0 3
  • 当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异...
    初来的雨天阅读 3,499评论 0 22
  • 有的人生是永远挣不脱的枷锁 有的人生是永远灭不了的火种 有些人的生活似霜敲打着枯茄 有些人的生活似光指引着心灵 他...
    流年飘雪阅读 271评论 1 4