定位mysql死锁_定位数据库死锁,和初步解决死锁办法

本文介绍了如何在MySQL中开启跟踪标志1204和1222以记录死锁信息,通过模拟死锁情况展示日志分析过程,找出引发死锁的SQL语句。并提出使用`with(nolock)`来解决由`SELECT`语句引起的死锁问题,但这种方法仅适用于不关心脏读的情况。
摘要由CSDN通过智能技术生成

1.目前我只是在sql 2008和2005上实验成功:

在数据库开启跟踪标识:

DBCC TRACEON(1204,-1)

DBCC TRACEON(1222,-1)

这两个跟踪标记都是将死锁写到错误日志中,不过1204是以文本格式进行,而1222是以XML格式保存。

开启后通过查看数据库日志文件就可以找到是那个语句引发死锁。

1.模拟一个死锁:

1 DBCC TRACEON(1204,-1)2 DBCC TRACEON(1222,-1)3

4 CREATE TABLE Lock1(C1 int default(0));5 CREATE TABLE Lock2(C1 int default(0));6 INSERT INTO Lock1 VALUES(1);7 INSERT INTO Lock2 VALUES(1);8

9 将以下脚本分别打开到两个查询分析器窗口中:10

11 1.12 Begin Tran

13 Update Lock1 Set C1=C1+1;14 WaitFor Delay '00:01:00';15 SELECT * FROMLock216 Rollback Tran;17

18 2.19 Begin Tran

20 Update Lock2 Set C1=C1+1;21 WaitFor Delay '00:01:00';22 SELECT * FROMLock123 Rollback Tran;

依次执行完毕后,稍后片刻会出现死锁详情:

17ed93a09032a35cd567c04d6aec257b.png

此时我们查看数据库日志:

3893b9069b5d68eb972321b3ee45830d.png

此时死锁有了,数据库日志也有了。万事俱备咱开始结合死锁说明和日志着手分析:

死锁通俗说明:

在死锁发生的时候,进程为54执行的sql语句和另外一个进程的sql语句共同光合作用下产生了死锁,但是系统会选择一个轻量级的进程当做牺牲品,干掉了这个进程,但是由于造成死锁的恰恰是另外一个进程的sql语句。所以必须首先找到另外一个进程的sql语句,死锁解决就指日可待了。

结合当前死锁说明,我们就知道,进程为54的这条不是造成死锁的原因,那么就是 日志文件里面进程为53的这条sql语句诱发了死锁。

1 进程53所执行的sql语句:2

3 Begin Tran

4 Update Lock1 Set C1=C1+1;5 WaitFor Delay '00:01:00';6 SELECT * FROMLock27 Rollback Tran;

针对症结对症下药:

结合网上的资料,使用with(nolock)来解决。with(nolock)只是针对select引发的死锁有效,并且对有可能产生的脏读不是很在意的时候可以采用此办法,否则还得另寻他路。

具体如下:

Begin Tran

Update Lock1 Set C1=C1+1;WaitFor Delay '00:01:00';SELECT * FROMLock2 whth(nolock)Rollback Tran;

此时在将模拟死锁的sql脚本在如法炮制一次你会发现,就不会出现死锁了如下所示:

50a0cf1ca3c6820c3b558c133143490c.png

9f99228cb5c0fb8948c6c80dd1a89ea3.png

以上针对sql的见解纯属本人愚见,同时也希望能够抛砖引玉。有说的不对的地方,还望大家给小弟说一下。

最后说明一下:

不足:这种方式只能坐等死锁发生后,开始着手解决。从战略上属于后发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值