mysql Innodb的锁和事物模型
2017-05-12 本文已影响120人
七海的游风
1.共享锁和独占锁
Innodb实现了标准行级锁,锁的类型有两种shared (S) locks 和 exclusive (X) locks.
- shared (S) locks:事物读的时候加S锁
- exclusive (X) locks: 事物更新,删除加X锁
如果事物t1持有某一行的S锁,其他事物请求对该行加锁的情况如下:
1.请求加S锁可以
2.请求加X锁需要等待
就是标准的读写锁加锁条件。
读写所有三个状态:无锁,读锁,写锁
可以加读锁的状态有:1.无锁2.读锁
可以加写锁的状态有:1.写锁
mysql使用可串行化隔离级别对加锁进行实验:
<待补充>
2.意向锁
- 意向锁是一种表级锁,意向锁不会真的加锁,只是代表有事物正在加锁或者马上准备加锁。意向锁也分为共享锁(IS)和独占锁(IX).
- IS锁:事务意图在表上获取一个或多个独立的行的S锁
- IX锁:事务意图在表上获取一个或多个独立的行的X锁
例如:
- SELECT ... LOCK IN SHARE MODE 会设置IS锁
- SELECT ... FOR UPDATE会设置IX锁
意向锁协议:
- 事务获取S锁之前必须先获取IS锁或者更强类型的锁
- 事务获取X锁之前必须先获取IX锁
意向锁加锁兼容性:
- | X | IX | S | IS
------| ------ | ------ | ------ | ------
X | Conflict | Conflict | Conflict | Conflict
IX | Conflict | Compatible | Conflict | Compatible
S | Conflict | Conflict | Compatible | Compatible
IS | Conflict | Compatible | Compatible | Compatible
3.记录锁(R锁)
- 记录锁在索引记录上加锁,即使表上没有索引在innodb中也会对聚族索引加锁(innodb内部机制有索引会使用已存在的索引聚族没有的话会生成一个隐藏的索引)。
- SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE会对c1加R锁,阻止其他事物插入,更新,删除c1=10的记录。只会锁住索引上的一个记录。
4.Gap锁(G锁,间隙锁)
- 与R锁不同,R锁只锁索引记录,G锁锁定的是索引间隙,或者范围内的索引记录<非唯一索引>。SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 这条sql会阻止其他事物插入一个t.c1是15的行,t.c1=15这条记录存不存在,因为在10到20之间的间隙都已经被加锁,如果t.c1不是unique的name,t.c1=15也算是间隙,应该被锁住的。
- Gap锁只阻止不能再间隙内插入数据,所以GAP的X锁和S锁有一样的语义,多个事务可以同时持有Gap锁。
- 间隙锁可能锁住一个索引值,也可能是多个,甚至是一个都不会锁定。
- SELECT * FROM child WHERE id = 100; 如果id是唯一索引这里会加上R锁,如果不是唯一索引这里会加GAP锁。
- 在Read COMMITTED隔离级别下GAP锁会失效
5.Next-Key Locks
6.Insert Intention Locks(插入意向锁)
7.AUTO-INC Locks
未完待续...