本文介绍的InnoDB中的锁是基于MySQL5.7版本。本文主要是翻译字MySQL5.7的文档手册,地址https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html
本文主要介绍了MySQL5.7版本中InnoDB存储引擎使用的锁类型。
1. 共享锁和排他锁(Shared and Exclusive Locks)
InnoDB实现了行级锁,在行级锁中包括两种锁,分别如下:
- 共享锁:如果事务持有共享锁,则能够读取亢数据
Next-key locks
next-key lock就是索引记录上的record lock和在这个索引记录之前的gap lock的结合。InnoDB在通过索引进行操作时,是给匹配到的索引记录添加共享或排他锁。从这点上来说,InnoDB上的行级锁就是索引上的锁。
针对索引中的R记录,next-key lock是包括在R上的锁以及R索引前的gap lock。这样,如果一个事务持有一个R上的锁,那么另一个事务是不能在R之前的记录中添加记录了。
InnoDB在Repeatable read事务水平时,会使用next-key lock来进行搜索和索引扫描,这阻止了幻读。
InnoDB行锁实现方法
InnoDB中的行锁,只有通过索引检索数据,InnoDB才使用行级锁,否则使用表级锁。可以通过explain来查看sql语句是否使用了索引。针对某些小表,即使写了索引,可能也不一定会走索引,这种清空是会锁表的。
InnoDB间隙锁-Gap Locks
gap锁是在索引之间或第一个索引值前或最后一个索引值后上的锁(范围)。select c1 from t where c1 between 10 and 20 for update;
,会给记录在10到20间上面添加gao锁。
gap锁可能跨越一个索引,多个索引,甚至可能为空。
gao锁在RC隔离级别下不适用,在PR级别下使用。
如果是查询唯一索引并且命中,则不会添加gap锁(但是如果唯一索引由多个列组成,并且where条件中只写了部分列,仍然添加gap锁)。select * from child where id=100;
,其中id是唯一索引,这条语句只会在id=100的索引上添加索引锁。如果没有命中100或者id不是唯一索引,则会对100之前的间隙添加gap。
针对同一个间隙,不同的事务可以在间隙上添加gap lock。
InnoDB在不同的隔离级别下
InnoDB在不同的隔离级别下采用的锁时不同的。
网友评论