(转)mysql 中的 latch锁和Tlock(事务锁), DML加锁规则,以及死锁分析

mysql 中的 latch锁和Tlock(事务锁), DML加锁规则,以及死锁分析。

一.Latch和Tlock的关系

Latch:为保护临界资源的正确性而设计,例如保护正在使用的内存页面不被破坏等。

没有死锁检测机制,轻量锁,并且作用对象时内存页面或是内存共享变量.

Tlock:事务锁,作用对象是事务,有死锁检测机制.

在innodb内部,为了减少死锁的发生概率,Latch不会等待Tlock.

线程获取行锁的流程:

在对行加锁的时候会先对行所在的页面添加lath,然后再对行添加Tlock,待对行添加完Tlock后再释放页面的Lath。

这种机制主要是为了保证线程获取的行数据的一致性和完整性.

如果行被其他的线程占有,线程先释放页面latch,等待行锁,待获取行锁后会再次对页面添加latch,查看页面数据是否有改动,再次获取改动后的行。

二.DML加锁规则

DML加锁的语句有,insert/update ... where ..../ delete from  .. where .. /  select * from  

insert不添加锁,但是在有唯一所以的时候,会对唯一索引做唯一性检查(加s锁,在将s锁转化为x锁),都是行锁。

update ... where.. / delete ... where ../select ... where lock in share mode / select .. where .. for update 

(1).数据查找走了索引,但是表达式为不等号,则会添加区间锁(gap).

例如. > 10  ,则锁定区间为(10,+~)

<10 ,则锁定区间为(-~,10) .

(2).数据查找走的唯一索引,并且表达式为等号(=),则添加行锁(record lock but not gap) 。

(3).数据查找为非唯一索引,并且表达式为等号,会添加区间锁(record lock gap),会锁定的区间为( ] ,允许更新,不允许插入.

重点:区间锁是为了防止出现幻觉读的,所以只阻塞插入操作.对更新不影响

三.死锁案例分析.

(1).insert,并发插入相同的数据,并且插入字段中有唯一键存在,

在正常的插入过程中是不会添加任何锁的,但是在有唯一键的时候会对唯一键的字段做唯一性检查,在检查的过程中会对记录共享锁(S),

当多个线程对同一行添加共享锁(S)之后,会将共享锁(s)转化为排他锁(X),此时就会相互等待,产生死锁.

(2).update并发更新,更新的字段有索引

线程一根据索引字段更新一个行,线程二根据主键更新索引字段.

此时线程一获得了索引等待行 ,线程二获得了行等待索引。

(3)delete,根据某一个唯一索引字段并发删除记录。

过程非常复杂,详情见一下链接:

http://www.cnblogs.com/sunss/p/3166550.html

(4).insert和delete并发,有非聚集索引

线程1根据某个非聚集索引字段删除数据,线程2插入相同的记录。

线程1获得了索引,等待行,线程2获得了行,等待索引。

(5).insert 和update并发,有非聚集索引。

死锁原理同4.

(6)delete 和update 并发.

原理同2.

死锁案例连接:

innodb next-key lock引发的死锁:

http://www.cnblogs.com/xhan/p/3701459.html

唯一键造成的死锁:

http://www.cnblogs.com/sunss/p/3166550.html

mysql中的delete死锁

http://hedengcheng.com/?p=844

http://dwchaoyue.blog.51cto.com/2826417/1749109

原文地址:https://www.cnblogs.com/sq892246139/p/7675690.html