Skip to the content.

..

InnoDB 锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。

在数据库中,处理传统的计算资源(如CPU、RAM、I/O等)的竞争外,数据也是一种共享资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题;如果加锁过度,会极大的降低并发处理能力。

参考:15.7.1 InnoDB Locking

InnoDB实现标准的行级锁,分为 共享锁和排它锁。

Shared and Exclusive Locks

假设事务T1有row1的S锁,然后另一个事务T2也对row1进行获得锁请求?

如果事务T1对row1持有X锁,则不能立即批准另一个事务T2对row1任何类型锁的请求;T2必须等待事务T1释放row1的锁定。

Intention Locks

InnoDB支持多种粒度锁定,允许行锁和表锁并存。

例如:LOCK TABLES … WRITE之类语句对指定表采用X锁。

为了支持多个粒度级别的锁,InnoDB使用I(意向)锁。

意向锁是表级锁,表示事务稍后对表中的行需要那种类型的锁(S X)。

两种类型的I锁

例如: SELECT ... FOR SHARE可设置IS, SELECT ... FOR UPDATE设置IX

意向锁协议

  1. 当事务要获取表中某行共享锁(S锁)之前,必须首先获取该表意向共享锁(IS)或者更强的锁
  2. 当事务要获取表中某行的排它锁(X锁)之前,必须首先获取该表意向排它锁(IX)

表级锁兼容汇总

IX表锁不与S行锁兼容;行锁只与S、IS兼容。

  X IX S IS
X 冲突 冲突 冲突 冲突
IX 冲突 兼容 冲突 兼容
S 冲突 冲突 兼容 兼容
IS 冲突 兼容 兼容 兼容

如果一个锁与现有锁兼容,则将其授予请求的事务,反之冲突则不授予;

事务等待直到冲突的现有锁释放。

如过锁定请求与现有锁定发生冲突,并且由于可能导致死锁而无法授予,则会发生错误。

Record Locks

记录锁(Record Lock),是对索引记录的锁定;例如 SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;语句会阻止其他事务插入/更新/或删除 t.c1 值为 10的行。

记录锁始终锁定索引记录,即使没有定义索引的表也是如此;对于没有这种情况,InnoDB 会创建一个隐藏的聚集索引(clustered index, 也称为聚簇索引)并将该索引用于记录锁定。

Gap Locks

间隙锁定是对索引记录之间的间隙的锁定。

例如: SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;防止其它事务将值15插到t.c1中,无论该列中是否已有这样的值,因为该范围中所有值之间的间隙是锁定的

Next-Key Locks

是一个索引锁和索引记录之前的间隙锁的组合;

(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

对于最后一个区间,Next-Key锁施加一个无穷大的伪记录上,从而会锁住大于最大值20的间隙。这个伪记录具有大于所有实际存在于索引的值。无穷大记录不是真实存在的,因此,实际上它上面的Next-Key锁只锁住最大值20之后的间隙。

综上三锁

record lock、gap lock、next-key lock,都是作用在索引上的。假设有记录1,3,5,7,则5上的记录锁会锁住5,5上的gap lock会锁住(3,5),5上的next-key lock会锁住(3,5]。

Insert Intention Locks

插入意向锁是一种在行插入之前通过INSERT操作设置的 gap lock;目的是为了插入的性能和正确。

这种锁表示要以这样的一种方式插入:如果多个事务插入到相同的索引间隙中,如果它们不在间隙中的相同位置插入,则无需等待其他事务(不阻塞)

例如:有索引4和7之间的间隙,有两个事务分别想插入5、6,在获得插入行的X锁之前,每个锁都使用Insert Intention Locks来锁定4和7之间的间隙,但不互相阻塞,因为行是无冲突的。

AUTO-INC Locks

是一种特殊的表级锁,由插入到具体的 AUTO_INCREMENT列的表中的事务获取。

最简单的情况,如果一个事务正在向表中插入值,则任何其它事务都必须等待自己在该表中进行插入,以便第一个事务插入的行接收连续的主键值。

innodb_autoinc_lock_mode 配置可以控制用于自增锁算法;它让你可以选择如何在可预测的自增序列与插入操作的最大并发性之间进行权衡。

Predicate Locks for Spatial Indexes

空间索引的谓语锁;

InnoDB支持对包含空间列的列进行SPATIAL索引。