的锁类型InnoDB
.
InnoDB
实现标准的行级锁,其中有两种类型的锁,共享(年代
)锁而且独家(X
)锁.
如果事务T1
持有共享的(年代
锁定行r
,然后是来自不同事务的请求T2
对于行上的锁r
处理方法如下:
由
T2
对于一个年代
可以立即授予锁。结果,两者都有T1
而且T2
举行一次年代
锁上r
.由
T2
对于一个X
不能立即授予锁。
如果一个事务T1
持有独家(X
锁定行r
,一个来自不同事务的请求T2
对于任意一种类型的锁r
不能立即批准。相反,事务T2
必须等待交易T1
释放行上的锁r
.
InnoDB
支持多粒度锁定它允许行锁和表锁共存。例如,这样的语句锁表…写
接受排他锁(一个X
锁定)在指定表上。为了实现多个粒度级别的锁定,InnoDB
使用意向锁.意图锁是表级锁,它指示事务以后需要对表中的某一行使用哪种类型的锁(共享的或独占的)。有两种类型的意图锁:
例如,选择……为分享
设置一个是
锁,选择……更新
设置一个9
锁。
意图锁定协议如下:
事务在获取表中某一行上的共享锁之前,必须先获取
是
锁在桌子上或更强。事务在获得表中某一行的排他锁之前,必须先获得
9
锁在桌子上。
表级锁类型兼容性总结在下面的矩阵中。
X |
9 |
年代 |
是 |
|
---|---|---|---|---|
X |
冲突 | 冲突 | 冲突 | 冲突 |
9 |
冲突 | 兼容的 | 冲突 | 兼容的 |
年代 |
冲突 | 冲突 | 兼容的 | 兼容的 |
是 |
冲突 | 兼容的 | 兼容的 | 兼容的 |
如果锁与现有锁兼容,则将锁授予请求事务,但如果与现有锁冲突则不授予。事务等待,直到冲突的现有锁被释放。如果一个锁请求与一个现有的锁冲突,并且不能被授予,因为它会导致死锁,出现错误。
意图锁不阻塞任何东西,除了全表请求(例如,锁表…写
).意图锁的主要目的是显示某人正在锁定一行,或将锁定表中的一行。
意图锁的事务数据类似于下面的显示引擎innodb状态
而且InnoDB监控输出:
锁定“test”表。' t ' trx id 10080锁定模式IX
记录锁是索引记录上的锁。例如,SELECT c1 FROM t WHERE c1 = 10
阻止任何其他事务插入、更新或删除值所在的行t.c1
是10
.
记录锁总是锁定索引记录,即使表定义时没有索引。对于这种情况,InnoDB
创建一个隐藏的聚集索引,并使用该索引进行记录锁定。看到第15.6.2.1节“群集索引和二级索引”.
记录锁的事务数据类似于下面的显示引擎innodb状态
而且InnoDB监控输出:
记录锁空间id 58页编号3 n位72索引' PRIMARY '表' test '。' t ' trx id 10078 lock_mode X锁定rec而不是gap记录锁,堆没有2物理记录:n_fields 3;紧凑的格式;0: len 4;十六进制8000000;asc;;1: len 6;十六进制00000000274 f;asc的啊;;2: len 7; hex b60000019d0110; asc ;;
间隙锁是对索引记录之间的间隙的锁,或者对第一个索引记录之前或最后一个索引记录之后的间隙的锁。例如,SELECT c1 FROM t WHERE c1在10到20之间
阻止其他事务插入值15
成列t.c1
,无论列中是否已经有任何这样的值,因为范围中所有现有值之间的空白都是锁定的。
间隙可能跨越单个索引值、多个索引值,甚至为空。
间隙锁是性能和并发性之间权衡的一部分,在某些事务隔离级别中使用,而在其他事务隔离级别中不使用。
对于使用惟一索引锁定行以搜索惟一行的语句,不需要间隙锁定。(这不包括搜索条件只包括多列唯一索引的某些列的情况;在这种情况下,间隙锁定就会发生。)例如,如果id
列具有惟一的索引,则以下语句仅对具有的行使用索引记录锁id
值为100,其他会话是否在前面的间隙中插入行无关紧要:
SELECT * FROM child WHERE id = 100;
如果id
没有索引或具有非惟一索引,则该语句将锁定前面的间隙。
这里还值得注意的是,冲突锁可以由不同的事务持有在一个间隙上。例如,事务A可以持有一个间隙上的共享间隙锁(间隙s锁),而事务B可以持有同一个间隙上的独占间隙锁(间隙x锁)。允许间隙锁冲突的原因是,如果从索引中清除一条记录,则必须合并不同事务在该记录上持有的间隙锁。
间隙锁紧InnoDB
是”纯粹是禁止的”,这意味着它们的唯一目的是防止其他交易插入缺口。间隙锁可以共存。一个事务使用的间隙锁并不阻止另一个事务在同一间隙上使用间隙锁。共享和排他间隙锁之间没有区别。它们彼此不冲突,并且它们执行相同的功能。
间隙锁定可以显式禁用。如果将事务隔离级别更改为,则会发生此情况读过承诺
.在这种情况下,间隙锁定对搜索和索引扫描禁用,只用于外键约束检查和重复键检查。
的使用还有其他影响读过承诺
隔离级别。不匹配行的记录锁在MySQL计算完在哪里
条件。为更新
语句,InnoDB
一个”semi-consistent”,这样它就会返回最新的提交版本给MySQL,这样MySQL就可以确定行是否匹配在哪里
的条件更新
.
下一键锁是索引记录上的记录锁和索引记录前间隙上的间隙锁的组合。
InnoDB
执行行级锁定的方式是,在搜索或扫描表索引时,在遇到的索引记录上设置共享或排他锁。因此,行级锁实际上是索引记录锁。索引记录上的下一个键锁也会影响”差距”在索引记录之前。也就是说,下一个键锁是索引记录锁加上索引记录前间隙锁。如果一个会话记录上有共享锁或独占锁R
在索引中,另一个会话不能在紧接之前的间隙中插入新的索引记录R
按索引顺序排列。
假设索引包含值10、11、13和20。该索引可能的下一个键锁覆盖以下间隔,其中圆括号表示不包含间隔端点,方括号表示包含该端点:
(负无穷,10](10,11](11,13](13,20](20,正无穷)
对于最后一个间隔,next-key锁锁定索引中最大值和”上确界”伪记录的值大于索引中的实际值。上值并不是一个真正的索引记录,因此,实际上,这个下一个键锁只锁定最大索引值之后的间隙。
默认情况下,InnoDB
在可重复读取
事务隔离级别。在这种情况下,InnoDB
使用下一个键锁进行搜索和索引扫描,这可以防止幻行(参见第15.7.4节“幻影行”).
下一个键锁的事务数据类似于下面的显示引擎innodb状态
而且InnoDB监控输出:
记录锁空间id 58页编号3 n位72索引' PRIMARY '表' test '。' t ' trx id 10080 lock_mode X记录锁,堆没有1物理记录:n_fields 1;紧凑的格式;信息位0 0:len 8;十六进制73757072656 d756d;asc上确界;;物理记录:n_fields 3;紧凑的格式;0: len 4;十六进制8000000; asc ;; 1: len 6; hex 00000000274f; asc 'O;; 2: len 7; hex b60000019d0110; asc ;;
插入意图锁是一种间隙锁插入
行插入之前的操作。该锁表示要以这样一种方式插入,即插入到同一索引间隙的多个事务如果不在间隙内的同一位置插入,则不需要相互等待。假设有值为4和7的索引记录。分别尝试插入值5和6的独立事务,每个事务在获得插入行上的排它锁之前,都会用插入意图锁锁定4和7之间的间隙,但不会阻塞彼此,因为行是不冲突的。
下面的例子演示了一个事务在获取插入记录的排他锁之前先获取一个插入意图锁。该示例涉及两个客户机A和B。
客户端A创建一个包含两个索引记录(90和102)的表,然后启动一个事务,在ID大于100的索引记录上放置排他锁。排他锁包括记录102之前的间隙锁:
CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;mysql> INSERT INTO child (id) values (90),(102);mysql> START TRANSACTION;SELECT * FROM child WHERE id > 100 FOR UPDATE;+-----+ | id | +-----+ | 102 | +-----+
客户端B开始一个事务,在间隙中插入一条记录。事务在等待获取排他锁时接受一个插入意图锁。
mysql> START TRANSACTION;mysql> INSERT INTO child (id) VALUES (101);
插入意图锁的事务数据类似于下面的显示引擎innodb状态
而且InnoDB监控输出:
记录锁空间id 31页编号3 n位72索引' PRIMARY '的表' test '。' child ' trx id 8731 lock_mode X锁定rec插入意图等待前的间隙,记录锁定,堆没有3物理记录:n_fields 3;紧凑的格式;0: len 4;十六进制80000066;asc f;;1: len 6;十六进制000000002215;Asc ";;2: len 7; hex 9000000172011c; asc r ;;...
一个AUTO-INC
Lock是一种特殊的表级锁,用于插入表中的事务AUTO_INCREMENT
列。在最简单的情况下,如果一个事务正在向表中插入值,那么任何其他事务都必须等待自己对该表进行插入,以便第一个事务插入的行接收连续的主键值。
的innodb_autoinc_lock_mode
变量控制用于自动增量锁定的算法。它允许您选择如何在可预测的自动递增值序列和插入操作的最大并发性之间进行权衡。
有关更多信息,请参见第15.6.1.6节“InnoDB中的AUTO_INCREMENT处理”.
InnoDB
支持空间
包含空间数据的列的索引(参见第11.4.9节“优化空间分析”).
处理涉及的操作的锁定空间
索引、下一键锁定不能很好地支持可重复读取
或可序列化的
事务隔离级别。在多维数据中没有绝对的排序概念,因此不清楚哪个是”下一个”关键。
启用表的隔离级别支持空间
索引,InnoDB
使用谓词锁。一个空间
索引包含最小边界矩形(MBR)值,因此InnoDB
通过在用于查询的MBR值上设置谓词锁,强制对索引进行一致的读取。其他事务不能插入或修改与查询条件匹配的行。