|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册账号
×
本帖最后由 windy8848 于 2011-4-15 09:54 编辑
- 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
- /********************************************************
- // 创建: fengyu 邮件: maggiefengyu@tom.com
- // 日期:2004-04-30
- // 修改: 从 http://www.csdn.net/develop/Read_Article.asp?id=26566 学习到并改写
- // 说明: 查看数据库里阻塞和死锁情况
- ********************************************************/
- 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 master.dbo.sysprocesses where blocked>0 ) a
- where not exists(select * from (select * from master.dbo.sysprocesses
- where blocked>0 ) b
- where a.blocked=spid)
- union
- select spid,blocked
- from master.dbo.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
- --需要的时候直接调用:
- exec sp_who_lock
- --MSSQL(查找死锁):
-
- use master
- go
- declare @spid int,@bl int
- DECLARE s_cur CURSOR FOR
- select 0 ,blocked
- from (select * from master..sysprocesses where blocked>0 ) a
- where not exists(select * from (select * from master..sysprocesses where blocked>0 ) b where a.blocked=spid)
- union
- select spid,blocked from master..sysprocesses where blocked>0
- OPEN s_cur
- FETCH NEXT FROM s_cur INTO @spid,@bl
- WHILE @@FETCH_STATUS = 0
- 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 )
- FETCH NEXT FROM s_cur INTO @spid,@bl
- end
- CLOSE s_cur
- DEALLOCATE s_cur
-
-
- exec sp_who2
-
-
- --邹建的过程
- create proc sp_lockinfo
- @kill_lock_spid bit=1, --是否杀掉阻塞的进程,1 杀掉, 0 仅显示
- @show_spid_if_nolock bit=1, --如果没有阻塞的进程,是否显示正常进程信息,1 显示,0 不显示
- @dbname sysname='' --如果为空,则查询所有的库,如果为null,则查询当前库,否则查询指定库
- as
- set nocount on
- declare @count int,@s nvarchar(2000),@dbid int
- if @dbname='' set @dbid=db_id() else set @dbid=db_id(@dbname)
-
- select id=identity(int,1,1),标志,
- 进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,
- 数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,
- 登陆时间=login_time,打开事务数=open_tran, 进程状态=status,
- 工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,
- 域名=nt_domain,网卡地址=net_address
- into #t from(
- select 标志='阻塞的进程',
- spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,
- status,hostname,program_name,hostprocess,nt_domain,net_address,
- s1=a.spid,s2=0
- from master..sysprocesses a join (
- select blocked from master..sysprocesses
- where blocked>0
- and(@dbid is null or dbid=@dbid)
- group by blocked
- )b on a.spid=b.blocked
- where a.blocked=0
- and(@dbid is null or dbid=@dbid)
- union all
- select '|_牺牲品_>',
- spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,
- status,hostname,program_name,hostprocess,nt_domain,net_address,
- s1=blocked,s2=spid
- from master..sysprocesses a
- where blocked<>0
- and(@dbid is null or dbid=@dbid)
- )a order by s1,s2
-
- select @count=@@rowcount
-
- if @count=0 and @show_spid_if_nolock=1
- begin
- insert #t
- select 标志='正常的进程',
- spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,
- open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address
- from master..sysprocesses
- where @dbid is null or dbid=@dbid
- order by spid
- set @count=@@rowcount
- end
-
- if @count>0
- begin
- create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))
- declare tb cursor local
- for
- select N'insert #t1 exec(''dbcc inputbuffer('+rtrim(进程ID)+')'')
- if @@rowcount=0 insert #t1(a) values(null)
- '+case when @kill_lock_spid=1 and 标志=N'阻塞的进程'
- then 'kill '+rtrim(进程ID) else '' end
- from #t
- open tb
- fetch tb into @s
- while @@fetch_status=0
- begin
- exec(@s)
- fetch tb into @s
- end
- close tb
- deallocate tb
- select a.*,进程的SQL语句=b.EventInfo
- from #t a join #t1 b on a.id=b.id
- order by a.ID
- end
- set nocount off
- go
复制代码 |
|