共享和排他锁

InnoDB 实现了两种标准的row-level locking——共享锁shared(S) locks 和 排他锁exclusive(X) locks.
  • 一个 shared(S) locks 允许事务持有这个锁来读取一行数据
  • 一个 exclusive(X) locks 允许事务持有这个锁来更新或删除一行数据.

如果事务 T1 在第r行数据上持有一个共享锁,当另一个事务T2来请求第r行数据上的锁时,会这样:
  • 事务T2请求S锁可以立刻得到,结果是,T1和T2都能获得在第r行上的S锁。
  • 事务T2请求X锁则不能立刻被授予。
如果事务T1在第r行上持有一个X锁,那么:
  • 事务T2请求第r行上任何类型的锁都不能被立刻授予。
  • T2必须等待T1释放在第r行上的锁。

意向锁

InnoDb支持多种粒度的锁,允许行级锁和表级锁共存。
意向锁是InnoDB中的表级锁,用于指示该表中某一行的某个事务需要哪种类型的锁(共享或排他)。
意向锁有两种类型:
  • Intention shared (IS): 事务T打算在表t的某些行上设置S锁。
  • Intention exclusive (IX): 事务T打算在表t的某些行上设置X锁。
意向锁的协议如下:
  • 在一个事务可以获取到t表的一行数据的S锁之前,它必须先获取一个t表的 IS 或者更强的锁。
  • 在一个事务可以获取到X锁之前,它必须先获取到一个t表的IX锁。
规则如下表:

X
IX
S
IS
X
Conflict
Conflict
Conflict
Conflict
IX
Conflict
兼容
Conflict
兼容
S
Conflict
Conflict
兼容
兼容
IS
Conflict
兼容
兼容
兼容


当一个事务请求锁时,只有和已存在的锁兼容,才能获取成功。否则事务会等待直到,已存在的冲突的锁被释放。如果事务最终无法获得锁,则可能是由于死锁deadlock
因此,意向锁不会阻止任何请求(除了全表的请求)。意向锁的主要目的是:展示有事务正在锁定一行,或者将要锁定一行。

记录锁 Record Locks

记录锁是一个在索引记录上的锁,例如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;
会阻止其他事务插入、修改、删除那些t.c1等于10的行。
记录锁总会锁定索引记录,即使表没有定义任何索引。

Gap Locks

一个gap lock是锁在索引记录的一定范围。例如SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止其他事务插入t.c1在10~20之间的记录,无论t.c1是否已经有这样的值,因为间隙范围内所有存在的记录都被锁定了。
一个gap lock可能跨域一个或多个值,甚至为空。
gap lock是性能和并发性之间的交易,在一些事务隔离级别中使用。
对于使用唯一索引锁定行以搜索一行的语句,不需要使用间隙锁定。
这里也值得注意的是,不同的事务可以在gap上保持冲突的锁。例如,事务A可以在gap上保持共享的间隙锁(间隙S锁),而事务B在同一gap上保持独占间隙锁(间隙X锁)。允许冲突间隙锁定的原因是,如果从索引中清除记录,则必须合并由不同事务记录保持的间隙锁定。

Next-Key Locks

在默认情况下,mysql的事务隔离级别是可重复读,这时默认采用next-key locks。所谓Next-Key Locks,就是Record lock和gap lock的结合。InnoDB以这样一种方式执行行级锁定,即当它搜索或扫描表索引时,它会在遇到的索引记录上设置共享锁或排它锁。
因此,行级锁实际上是索引记录锁。
索引记录上的next-key locks也会影响该索引记录之前的“间隙”。

也就是说,next-key locks是一个索引记录锁,并在索引记录之前的间隙上加上一个gap锁。

如果一个会话对索引中的记录R具有共享或独占锁定,则另一个会话不能在索引顺序中的R之前的间隙中插入新的索引记录。

假设索引包含值10,11,13和20.此索引的可能Next-Key Locks涵盖以下区间,其中圆括号表示排除区间端点,方括号表示包含端点:
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

插入意向锁 Insert Intention Locks

insert intention lock是插入行之前设置的一种gap lock这个锁发信号通知插入意图,以通知插入到相同gap中的多个事务,如果没有插入gap中相同位置时不需要等待对方。

假设有索引记录的值为4和7.分别尝试插入5和6的值的事务分别在获得对插入行的排它锁之前用插入意向锁来锁定4和7之间的间隔,但不要相互阻塞,因为行是非冲突的。

自增锁 AUTO-INC Locks

AUTO-INC锁是一个特殊的表级锁。在最简单的情况下,如果一个事务正在向表中插入值,则任何其他事务都必须等待自己插入到该表中,以便第一个事务插入的行接收连续的主键值。innodb_autoinc_lock_mode配置选项控制用于AUTO-INC的算法。


成为你想看到的世界变革力量

创建者:万乐荣
最后更新时间 : 2017年11月8日 16:34

评论