找回密码
 注册账号

QQ登录

只需一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

初学者课程:T3自学|T6自学|U8自学软件下载课件下载工具下载资料:通资料|U8资料|NC|培训|年结积分规则 | 使用常见问题Q&A
知识库:U8 | | NC | U9 | OA | 政务U8|U9|NCC|NC65|NC65客开|NCC客开新手必读 | 任务 | 快速增金币用友QQ群[微信群]
查看: 5262|回复: 12

[经验] 【收集】查看数据库里阻塞和死锁情况

[复制链接]
发表于 2010-11-8 10:03:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册账号

×
本帖最后由 windy8848 于 2011-4-15 09:54 编辑

  1. if exists (select * from dbo.sysobjects
  2. where id = object_id(N'[dbo].[sp_who_lock]')
  3. and OBJECTPROPERTY(id, N'IsProcedure') = 1)
  4. drop procedure [dbo].[sp_who_lock]
  5. GO
  6. /********************************************************
  7. //  创建: fengyu  邮件: maggiefengyu@tom.com
  8. //  日期:2004-04-30
  9. //  修改: 从 http://www.csdn.net/develop/Read_Article.asp?id=26566 学习到并改写
  10. //  说明: 查看数据库里阻塞和死锁情况
  11. ********************************************************/
  12. use master
  13. go
  14. create procedure sp_who_lock
  15. as
  16. begin
  17. declare @spid int,@bl int,
  18. @intTransactionCountOnEntry     int,
  19. @intRowcount             int,
  20. @intCountProperties         int,
  21. @intCounter             int
  22. create table #tmp_lock_who (
  23. id int identity(1,1),
  24. spid smallint,
  25. bl smallint)
  26. IF @@ERROR<>0 RETURN @@ERROR
  27. insert into #tmp_lock_who(spid,bl)
  28. select  0 ,blocked
  29. from (select * from master.dbo.sysprocesses where  blocked>0 ) a
  30. where not exists(select * from (select * from master.dbo.sysprocesses
  31. where  blocked>0 ) b
  32. where a.blocked=spid)
  33. union
  34. select spid,blocked
  35. from master.dbo.sysprocesses
  36. where  blocked>0
  37. IF @@ERROR<>0 RETURN @@ERROR
  38. -- 找到临时表的记录数
  39. select     @intCountProperties = Count(*),@intCounter = 1
  40. from #tmp_lock_who
  41. IF @@ERROR<>0 RETURN @@ERROR
  42. if    @intCountProperties=0
  43. select '现在没有阻塞和死锁信息' as message
  44. -- 循环开始
  45. while @intCounter <= @intCountProperties
  46. begin
  47. -- 取第一条记录
  48. select     @spid = spid,@bl = bl
  49. from #tmp_lock_who where Id = @intCounter
  50. begin
  51. if @spid =0
  52. select '引起数据库死锁的是:  进程号'+ CAST(@bl AS VARCHAR(10))
  53. + ', 其执行的SQL语法如下'
  54. else
  55. select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被'
  56. + '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
  57. DBCC INPUTBUFFER (@bl )
  58. end
  59. -- 循环指针下移
  60. set @intCounter = @intCounter + 1
  61. end
  62. drop table #tmp_lock_who
  63. return 0
  64. end
  65. --需要的时候直接调用:
  66. exec sp_who_lock



  67.   --MSSQL(查找死锁):  
  68.    
  69.   use   master   
  70.   go   
  71.   declare   @spid   int,@bl   int   
  72.   DECLARE   s_cur   CURSOR   FOR      
  73.   select     0   ,blocked   
  74.   from   (select   *   from   master..sysprocesses   where     blocked>0   )   a      
  75.   where   not   exists(select   *   from   (select   *   from   master..sysprocesses   where     blocked>0   )   b     where   a.blocked=spid)   
  76.   union   
  77.   select   spid,blocked   from   master..sysprocesses   where     blocked>0   
  78.   OPEN   s_cur   
  79.   FETCH   NEXT   FROM   s_cur   INTO   @spid,@bl   
  80.   WHILE   @@FETCH_STATUS   =   0   
  81.   begin   
  82.   if   @spid   =0      
  83.                           select   '引起数据库死锁的是:   '+   CAST(@bl   AS   VARCHAR(10))   +   '进程号,其执行的SQL语法如下'   
  84.   else   
  85.                           select   '进程号SPID:'+   CAST(@spid   AS   VARCHAR(10))+   '被'   +   '进程号SPID:'+   CAST(@bl   AS   VARCHAR(10))   +'阻塞,其当前进程执行的SQL语法如下'   
  86.   DBCC   INPUTBUFFER   (@bl   )   
  87.   FETCH   NEXT   FROM   s_cur   INTO   @spid,@bl   
  88.   end   
  89.   CLOSE   s_cur   
  90.   DEALLOCATE   s_cur   
  91.    
  92.   
  93.   exec sp_who2
  94.    
  95.    
  96.   --邹建的过程  
  97.   create   proc   sp_lockinfo  
  98.   @kill_lock_spid   bit=1,             --是否杀掉阻塞的进程,1   杀掉,   0   仅显示  
  99.   @show_spid_if_nolock   bit=1,   --如果没有阻塞的进程,是否显示正常进程信息,1   显示,0   不显示  
  100.   @dbname   sysname=''                     --如果为空,则查询所有的库,如果为null,则查询当前库,否则查询指定库  
  101.   as  
  102.   set   nocount   on  
  103.   declare   @count   int,@s   nvarchar(2000),@dbid   int  
  104.   if   @dbname=''   set   @dbid=db_id()   else   set   @dbid=db_id(@dbname)  
  105.    
  106.   select   id=identity(int,1,1),标志,  
  107.   进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,  
  108.   数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,  
  109.   登陆时间=login_time,打开事务数=open_tran, 进程状态=status,  
  110.   工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,  
  111.   域名=nt_domain,网卡地址=net_address  
  112.   into   #t   from(  
  113.   select   标志='阻塞的进程',  
  114.   spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,  
  115.   status,hostname,program_name,hostprocess,nt_domain,net_address,  
  116.   s1=a.spid,s2=0  
  117.   from   master..sysprocesses   a   join   (  
  118.   select   blocked   from   master..sysprocesses   
  119.   where   blocked>0  
  120.   and(@dbid   is   null   or   dbid=@dbid)  
  121.   group   by   blocked  
  122.   )b   on   a.spid=b.blocked   
  123.   where   a.blocked=0  
  124.   and(@dbid   is   null   or   dbid=@dbid)  
  125.   union   all  
  126.   select   '|_牺牲品_>',  
  127.   spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,  
  128.   status,hostname,program_name,hostprocess,nt_domain,net_address,  
  129.   s1=blocked,s2=spid  
  130.   from   master..sysprocesses   a   
  131.   where   blocked<>0  
  132.   and(@dbid   is   null   or   dbid=@dbid)  
  133.   )a   order   by   s1,s2  
  134.    
  135.   select   @count=@@rowcount  
  136.    
  137.   if   @count=0   and   @show_spid_if_nolock=1  
  138.   begin  
  139.   insert   #t  
  140.   select   标志='正常的进程',  
  141.   spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,  
  142.   open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address  
  143.   from   master..sysprocesses  
  144.   where   @dbid   is   null   or   dbid=@dbid  
  145.   order   by   spid  
  146.   set   @count=@@rowcount  
  147.   end  
  148.    
  149.   if   @count>0  
  150.   begin  
  151.   create   table   #t1(id   int   identity(1,1),a   nvarchar(30),b   Int,EventInfo   nvarchar(255))  
  152.   declare   tb   cursor   local  
  153.   for  
  154.   select   N'insert   #t1   exec(''dbcc   inputbuffer('+rtrim(进程ID)+')'')  
  155.   if   @@rowcount=0   insert   #t1(a)   values(null)  
  156.   '+case   when   @kill_lock_spid=1   and   标志=N'阻塞的进程'  
  157.   then   'kill   '+rtrim(进程ID)   else   ''   end  
  158.   from   #t  
  159.   open   tb  
  160.   fetch   tb   into   @s  
  161.   while   @@fetch_status=0  
  162.   begin  
  163.   exec(@s)  
  164.   fetch   tb   into   @s  
  165.   end  
  166.   close   tb  
  167.   deallocate   tb  
  168.   select   a.*,进程的SQL语句=b.EventInfo  
  169.   from   #t   a   join   #t1   b   on   a.id=b.id  
  170.   order   by   a.ID  
  171.   end  
  172.   set   nocount   off  
  173.   go
复制代码
发表于 2010-11-26 21:35:24 | 显示全部楼层
一个字:晕
发表于 2010-11-27 17:18:48 | 显示全部楼层
一个字,汗
发表于 2010-12-8 11:44:54 | 显示全部楼层
不错的问题跟踪思路,在sql数据库中很实用。
发表于 2011-3-3 12:48:30 | 显示全部楼层
没有试过
发表于 2011-3-3 12:49:43 | 显示全部楼层
楼主的代码也格式化下啊
发表于 2011-4-3 09:41:01 | 显示全部楼层
看得晕晕的~~~
发表于 2011-5-23 10:52:05 | 显示全部楼层
厉害 啊   强
发表于 2011-5-27 11:20:16 | 显示全部楼层
我的妈呀啊  真是的 真情啊
发表于 2011-8-3 11:20:25 | 显示全部楼层
好啊,顶一下
发表于 2011-8-23 10:32:40 | 显示全部楼层
做个记号,以后备用
发表于 2012-2-15 12:40:09 | 显示全部楼层
好东西,楼主厉害啊
回复 点赞 拍砖

使用道具 举报

发表于 2015-9-9 10:26:14 | 显示全部楼层
留下来学习了
回复 点赞 拍砖

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|站长微信|Archiver|手机版|小黑屋|用友之家 ( 蜀ICP备07505338号|51072502110008 )

GMT+8, 2024-4-20 12:20 , Processed in 0.058820 second(s), 7 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表