`
LiYunpeng
  • 浏览: 939011 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

MySQL,产生死锁的问题dead lock

阅读更多
首先,其实造成死锁的可能性也许每个人都不一样,所以重点不是如何解决问题,而是分析,也许我遇到的问题并不适用于其他人,但是遇到这种情况先要搞清楚,是哪个表,的哪个字段产生了资源征用,然后分析解决就可以了。

登录mysql后,通过show engine innodb status;来查看最后一次死锁的情况

查询后显示的
------------------------
LATEST DETECTED DEADLOCK
------------------------
块下面就是死锁的征用描述信息

里面会描述事物1、事物2....在执行某一语句的时候,对哪一个表的哪一个字段进行征用资源的时候,被什么类型的锁占用了

比如如下信息

RECORD LOCKS space id 47 page no 305 n bits 328 index PRIMARY of table `test`.`t_test` trx id 13806 lock_mode X locks gap before rec insert intention waiting

这里描述了
锁的类型,RECORD,锁得模式X,在准备申请插入意向锁的时候,在PRIMARY主键索引所在的空间47 页号305的328位的位置上产生了征用。


这里就要先熟悉几个概念
锁模式,X代表排它锁,S代表共享锁,IX代表表级排他锁,IS代表表级共享锁,他们之间在多线程/会话/事务的情况下,有可能同时使用,具体兼容关系可以参看官方文档
http://dev.mysql.com/doc/refman/5.5/en/innodb-locking.html

锁的类型也在上面的文档里有描述
RECORD 为记录级锁
GAP为记录区间范围的锁
Next-Key Locks为大于值,小于等于某个值的区间范围的锁
这些指的都是索引,其实也就是在操作表数据的时候,会先将索引锁住,尤其是PRIMARY和UNIQUE,这种唯一约束的索引,在操作的时候,数据库都会先查询数据库中的索引然后再进行相应操作。


了解了这些我们就可以分析,锁的资源征用情况
比如如下操作

表模型为
主键(自增,有主键索引)
其他列

开始事务1
事务1,执行delete语句删除某一个存在的值(锁住这条记录的索引)
事务1,插入一条新的记录,申请锁,等待这个锁被授权
开始事务2
事务2,执行delete语句删除某一个与事务1不同的存在的值(锁住这条记录的索引)
事务2,插入一条新的记录,申请锁,等待这个锁被授权
提交事务1
提交事务2

以上的操作不会造成资源竞争,因为两条delete删除的是指定的id的值。

但是当上面的操作,如果delete删除某一个不存在的值,那么就会将这个不存在的索引在所有索引里面去找,会找到一个区间范围,比如索引是10,20,要删除15,那么就会将索引10~20的范围进行锁死,而与此同时,另外一个事务也要锁这个区间范围,就会造成资源竞争。
两个事务的insert都在等待delete锁定的区间范围释放,然后执行插入,这样就造成了死锁

当然以上的只是其中一种情况,造成死锁的原因就是资源竞争,所以先查清楚哪个资源被竞争,执行哪一条语句时造成可,以及表的结构是怎样的很重要。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics