SQL Server死锁的分析

server

SQL Server数据库发生死锁时不会像ORACLE那样自动生成一个跟踪文件。有时可以在[管理]->[当前活动] 里看到阻塞信息(有时SQL Server企业管理器会因为锁太多而没有响应).
  设定跟踪1204:

USE MASTER
DBCC TRACEON (1204,-1)

  显示当前启用的所有跟踪标记的状态:

DBCC TRACESTATUS(-1)

  取消跟踪1204:

DBCC TRACEOFF (1204,-1)

  在设定跟踪1204后,会在数据库的日志文件里显示SQL Server数据库死锁时一些信息。但那些信息很难看懂,需要对照SQL Server联机丛书仔细来看。根据PAG锁要找到相关数据库表的方法:

DBCC TRACEON (3604)
DBCC PAGE (db_id,file_id,page_no)
DBCC TRACEOFF (3604)

  请参考sqlservercentral.com上更详细的讲解.但又从CSDN学到了一个找到死锁原因的方法。我稍加修改, 去掉了游标操作并增加了一些提示信息,写了一个系统存储过程sp_who_lock.sql。代码如下:

if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[sp_who_lock]')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_who_lock]
GO
/********************************************************
//  学习到并改写
//  说明 : 查看数据库里阻塞和死锁情况
********************************************************/
use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry     int,
@intRowcount             int,
@intCountProperties         int,
@intCounter             int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select  0 ,blocked
from (select * from sysprocesses where  blocked>0 ) a
where not exists(select * from (select * from sysprocesses
where  blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where  blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到临时表的记录数
select     @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if    @intCountProperties=0
select '现在没有阻塞和死锁信息' as message
-- 循环开始
while @intCounter <= @intCountProperties
begin
-- 取第一条记录
select     @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10))
+ '进程号,其执行的SQL语法如下'
else
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被'
+ '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
DBCC INPUTBUFFER (@bl )
end
-- 循环指针下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end

  需要的时候直接调用:

sp_who_lock

  就可以查出引起死锁的进程和SQL语句.

  SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。如果想知道其它tracenum参数的含义,请看http://www.sqlservercentral.com/文章

  我们还可以设置锁的超时时间(单位是毫秒), 来缩短死锁可能影响的时间范围:

  例如:

use master
seelct @@lock_timeout
set lock_timeout 900000
-- 15分钟
seelct @@lock_timeout

 

时间: 2025-01-20 21:25:45

SQL Server死锁的分析的相关文章

SQL Server 死锁案例分析

概述 当两个或者多个进程相互阻塞时,形成一个复杂的阻塞链,参与的进程都在等待其他进程放弃其获取到的锁,没有系统的干预,无法解开这个阻塞链,这种情况就是死锁. 有些死锁是意料之内的,可以说是故意为之的. 例如,为了一致性,使用死锁来防止丢失更新. 有一些死锁是意料之外的,由于缺少索引或者事务运行时间较长导致,我们遇到的大部分都是意料之外的死锁.  SQL Server内部有个死锁的检测机制,当发生死锁时,SQL Server根据会话优先级以及工作量进行评估, 选择终止其中一个事务,解开死锁,并且向

sql server死锁原因分析总结(1/2)

其实所有的死锁最深层的原因就是一个:资源竞争 sql server死锁表现一: 一个用户A 访问表A(锁住了表A),然后又访问表B 另一个用户B 访问表B(锁住了表B),然后企图访问表A 这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B,才能继续,好了他老人家就只好老老实实在这等了 同样用户B要等用户A释放表A才能继续这就死锁了 sql server死锁解决方法: 这种死锁是由于你的程序的BUG产生的,除了调整你的程序的逻辑别无他法 仔细分析你程序的逻辑, 1:尽量避免同时锁定两个资源

RDS SQL Server死锁(Deadlock)系列之五利用Extended Events获取死锁信息

问题引入 在过去很长一段时间,不断有客人会问道:"在事先没有任何跟踪或者监控部署的情况下,阿里云RDS SQL Server有没有办法获取到历史死锁信息,供我们分析?".在写到RDS SQL Server死锁系列文章之五时,我们就可以使用Extended Events来解决这个问题. 分析问题 Extended Events是微软从SQL Server 2008版本开始引入的,其中有一个默认事件会话是system_health,它的作用是用来收集SQL Server发生的错误信息,以X

RDS SQL Server死锁(Deadlock)系列之四利用Service Broker事件通知捕获死锁

问题引入 在前面三篇文章,我们分别谈到了使用DBCC命令捕获死锁:使用Profiler界面跟踪Deadlock Graph事件捕获死锁和使用脚本自动部署Profiler Trace捕获死锁.这篇文章介绍一个非常有意思的捕获死锁的方法:使用SQL Server Service Broker Event Notification来捕获死锁. Service Broker Event Notification Service Broker Event Notification即使用SQL Server

RDS SQL Server死锁(Deadlock)系列之二使用Profiler捕获死锁

问题引入 不管是RDS SQL Server还是自建SQL Server数据库,死锁的确是一个非常头疼的问题,上一篇文章我们已经谈到了使用DBCC捕获死锁.这篇文章是以阿里云RDS客户遇到的死锁问题为背景,分享死锁文章系列之二使用Profiler捕获死锁. Profiler捕获死锁 使用Profiler工具的Deadlock graph事件,可以非常方便直观的捕获死锁信息.方法是: 开启MSSQL Profiler:开始 -> 运行 -> 键入profiler 新建Deadlock Gra

RDS SQL Server死锁(Deadlock)系列之三自动部署Profiler捕获死锁

问题引入 系列SQL Server死锁系列文章之二,讲的是如何手动部署Profiler来捕获死锁以及对死锁发时场景重现,这篇文章是将这个手动部署的过程自动化话,实现一键部署,既快捷方便,又简单适用.上一篇文章,参见:使用Profiler捕获死锁. 自动部署Profiler 废话不多说,直接上代码,只需要初始化下面的Profiler停止时间@stop_time即可: use master GO set nocount on declare @trace_folder nvarchar(256) ,

RDS SQL Server死锁(Deadlock)系列之一使用DBCC捕获死锁

问题引入 在日常运维阿里云RDS SQL Server产品过程中,经常会被客户问道:"应用程序被死锁报错啦?影响很大,到底是哪个进程导致了死锁发生的啊?怎么解决啊?怎么办呀?".从客户一连串的问题中,我们深刻体会到了死锁问题的紧迫性和影响之大.授人予鱼而不如授人予渔,RDS SQL Server死锁系列文章就是为了帮助客人彻底解决死锁问题为初衷而诞生的.本篇文章是系列文章的开篇,主要是讨论如何使用DBCC来捕获死锁信息,内容包括: DBCC捕获死锁 死锁测试 死锁分析 解决方法

Sql Server 死锁的监控分析解决思路

1 背景 1.1 报警情况 最近整理笔记,打算全部迁移到EVERNOTE.整理到锁这一部分,里边刚好有个自己记录下来的案例,重新整理分享下给大家. 某日中午,收到报警短信,DB死锁异常,单分钟死锁120个. 死锁的xml文件如下: <deadlock-list> <deadlock victim="process810b00cf8"> <process-list> <process id="process810b00cf8"

sql server死锁的精辟解释

server sysprocessessysprocesses 表中保存关于运行在 Microsoft SQL Server 上的进程的信息.这些进程可以是客户端进程或系统进程.sysprocesses 只存储在 master 数据库中. 列名 数据类型 描述 spid smallint SQL Server 进程 ID. kpid smallint Microsoft Windows NT 4.0 线程 ID. blocked smallint 分块进程的进程 ID (spid). waitt