MySQL加锁分析 (转)

参考:MySQL 加锁处理分析。该文已经讲的很详尽了,也易懂,下面仅仅是我的作的总结。mysql

 

1、 背景

1.1 隔离级别

1.2 加锁过程

  逐条处理,逐条加锁。sql

update 执行流程

 

1.3 两阶段锁2PL

1.4 gap锁

  gap锁是间隙锁,即相邻两条有效记录间隙的锁(锁的是间隙),它是针对insert的,用来解决幻读的发生。它会阻塞insert,但不会阻塞delete/update等(记录原本也不存在)。session

  RC与RR的重要区别就是幻读。因此RR才须要引入gap锁。post

 

2、加锁组合分析

  说加什么锁,首先要了解两个前提:1)隔离级别;2)用到的索引。不一样的隔离级别,不一样的索引都会影响加锁。优化

2.1 可提交读RC

 

  主键/惟一键 二级索引 无索引
select
insert 行锁 行锁 行锁
select...for update/update/delete 行锁 有效行的行锁 全表锁聚簇索引

2.2 可重复读RR

 

  主键/惟一键 二级索引 无索引
select
insert 行锁 行锁 行锁
select...for update/update/delete 行锁 有效行的行锁+gap锁 全表锁聚簇索引

2.3 可序列化S

  主键/惟一键 二级索引 无索引
select(快照读) S S S
其余(当前读) X X X

 

  注意:无索引时,select...for update/update/delete是须要锁全表的,但mysql_server能够作优化,在逐条加锁时,若是发现不是目标记录,能够释放掉锁。但这会违背2PL的原则。spa

2.4 结论

  死锁的发生与否,并不在于事务中有多少条SQL语句,死锁的关键在于:两个(或以上)的Session加锁的顺序不一致。server

  加锁过程是逐条处理,逐条加锁(最终都反映在聚簇索引上)的。blog

  • 主键,加在聚簇索引上;
  • 二级索引,加在二级索引+聚簇索引上;
  • 无索引,加在聚簇索引上。

因此若是两个session用到不一样的二级索引,那么对聚簇索引的加锁顺序是不一致的,从而致使session间锁的持有与竞争,很容易产生死锁。索引

 

  • 做者:水岩
  • 出处:http://www.cnblogs.com/waterystone
  • 本博客中未标明转载的文章归做者水岩和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。
相关文章
相关标签/搜索