• 利用sys.sysprocesses检查SqlServer的阻塞和死锁


    Sys.SysProcesses 系统表是一个很重要的系统视图,主要用来定位与解决Sql Server的阻塞和死锁

    视图中主要的字段:
    1. Spid:Sql Servr 会话ID
    2. Kpid:Windows 线程ID
    3. Blocked:正在阻塞求情的会话 ID。如果此列为 Null,则标识请求未被阻塞
    4. Waittype:当前连接的等待资源编号,标示是否等待资源,0 或 Null表示不需要等待任何资源
    5. Waittime:当前等待时间,单位为毫秒,0 表示没有等待
    6. DBID:当前正由进程使用的数据库ID
    7. UID:执行命令的用户ID
    8. Login_time:客户端进程登录到服务器的时间。
    9. Last_batch:上次执行存储过程或Execute语句的时间。对于系统进程,将存储Sql Server 的启动时间
    10.Open_tran:进程的打开事务个数。如果有嵌套事务,就会大于1
    11.Status:进程ID 状态,dormant = 正在重置回话 ; running = 回话正在运行一个或多个批处理 ; background = 回话正在运行一个后台任务 ; rollback = 会话正在处理事务回滚 ; pending = 回话正在等待工作现成变为可用 ; runnable = 会话中的任务在等待获取 Scheduler 来运行的可执行队列中 ; spinloop = 会话中的任务正在等待自旋锁变为可用 ; suspended = 会话正在等待事件完成
    12.Hostname:建立链接的客户端工作站的名称
    13.Program_name:应用程序的名称,就是 连接字符串中配的 Application Name
    14.Hostprocess:建立连接的应用程序在客户端工作站里的进程ID号
    15.Cmd:当前正在执行的命令
    16.Loginame:登录名

    应用实例:

    1. 检查数据库是否发生阻塞

    先查找哪个链接的 blocked 字段不为0。如 SPID53的blocked 字段不为0,而是 52。SPID 52 的 blocked 为0,就可以得出结论:此时有阻塞发生,53 被 52 阻塞住了。如果你发现一个连接的 blocked 字段的值等于它自己,那说明这个连接正在做磁盘读写,它要等自己的 I/O 做完。

    2. 查找链接在那个数据库上

    检查 dbid 即可。得到 dbid,可以运行以下查询得到数据库的名字:
    Select name,dbid from master.sys.sysdatabases

    3. 查看此进程执行的SQL 是哪个,查找问题原因
    dbcc inputbuffer(spid);

    4. KILL 掉当前导致阻塞的SQL
    kill spid

    5. sql阻塞进程查询

    select A.SPID as 被阻塞进程,a.CMD AS 正在执行的操作,b.spid AS 阻塞进程号,b.cmd AS 阻塞进程正在执行的操作
    from master..sysprocesses a,master..sysprocesses b
    where a.blocked<>0 and a.blocked= b.spid
    
    exec sp_who 'active'--查看系统内所有的活动进程 BLK不为0的为死锁
    
    exec sp_lock 60 --返回某个进程对资源的锁定情况
    
    SELECT object_name(1504685104)--返回对象ID对应的对象名
    
    DBCC INPUTBUFFER (63)--显示从客户端发送到服务器的最后一个语句

    6. SQL Server简洁查询正在运行的进程SQL

    SELECT   spid,
             blocked,
             DB_NAME(sp.dbid) AS DBName,
             program_name,
             waitresource,
             lastwaittype,
             sp.loginame,
             sp.hostname,
             a.[Text] AS [TextData],
             SUBSTRING(A.text, sp.stmt_start / 2,
             (CASE WHEN sp.stmt_end = -1 THEN DATALENGTH(A.text) ELSE sp.stmt_end
             END - sp.stmt_start) / 2) AS [current_cmd]
    FROM     sys.sysprocesses AS sp OUTER APPLY sys.dm_exec_sql_text (sp.sql_handle) AS A
    WHERE    spid > 50
    ORDER BY blocked DESC, DB_NAME(sp.dbid) ASC, a.[text];


    SqlServer查询和Kill进程死锁的语句

    查询死锁进程语句

    1 select
    2 request_session_id spid, 
    3 OBJECT_NAME(resource_associated_entity_id) tableName 
    4 from
    5 sys.dm_tran_locks 
    6 where
    7 resource_type='OBJECT'

    下面再给大家分享一段关于sqlserver检测死锁;杀死锁和进程;查看锁信息

      1 --检测死锁
      2 --如果发生死锁了,我们怎么去检测具体发生死锁的是哪条SQL语句或存储过程?
      3 --这时我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句。SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。
      4 use master
      5 go
      6 create procedure sp_who_lock
      7 as
      8 begin
      9 declare @spid int,@bl int,
     10  @intTransactionCountOnEntry int,
     11   @intRowcount int,
     12   @intCountProperties int,
     13   @intCounter int
     14  create table #tmp_lock_who (
     15  id int identity(1,1),
     16  spid smallint,
     17  bl smallint)
     18  IF @@ERROR<>0 RETURN @@ERROR
     19  insert into #tmp_lock_who(spid,bl) select 0 ,blocked
     20  from (select * from sysprocesses where blocked>0 ) a 
     21  where not exists(select * from (select * from sysprocesses where blocked>0 ) b 
     22  where a.blocked=spid)
     23  union select spid,blocked from sysprocesses where blocked>0
     24  IF @@ERROR<>0 RETURN @@ERROR 
     25 -- 找到临时表的记录数
     26  select @intCountProperties = Count(*),@intCounter = 1
     27  from #tmp_lock_who
     28  IF @@ERROR<>0 RETURN @@ERROR 
     29  if @intCountProperties=0
     30  select '现在没有阻塞和死锁信息' as message
     31 -- 循环开始
     32 while @intCounter <= @intCountProperties
     33 begin
     34 -- 取第一条记录
     35  select @spid = spid,@bl = bl
     36  from #tmp_lock_who where Id = @intCounter 
     37  begin
     38  if @spid =0 
     39    select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10)) + '进程号,其执行的SQL语法如下'
     40  else
     41    select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '' + '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
     42  DBCC INPUTBUFFER (@bl )
     43  end
     44 -- 循环指针下移
     45  set @intCounter = @intCounter + 1
     46 end
     47 drop table #tmp_lock_who
     48 return 0
     49 end
     50 --杀死锁和进程
     51 --如何去手动的杀死进程和锁?最简单的办法,重新启动服务。但是这里要介绍一个存储过程,通过显式的调用,可以杀死进程和锁。
     52 use master
     53 go
     54 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
     55 drop procedure [dbo].[p_killspid]
     56 GO
     57 create proc p_killspid
     58 @dbname varchar(200) --要关闭进程的数据库名
     59 as
     60  declare @sql nvarchar(500) 
     61  declare @spid nvarchar(20)
     62  declare #tb cursor for
     63   select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
     64  open #tb
     65  fetch next from #tb into @spid
     66  while @@fetch_status=0
     67  begin
     68   exec('kill '+@spid)
     69   fetch next from #tb into @spid
     70  end
     71  close #tb
     72  deallocate #tb
     73 go
     74 --用法 
     75 exec p_killspid 'newdbpy'
     76 --查看锁信息
     77 --如何查看系统中所有锁的详细信息?在企业管理管理器中,我们可以看到一些进程和锁的信息,这里介绍另外一种方法。
     78 --查看锁信息
     79 create table #t(req_spid int,obj_name sysname)
     80 declare @s nvarchar(4000)
     81  ,@rid int,@dbname sysname,@id int,@objname sysname
     82 declare tb cursor for
     83  select distinct req_spid,dbname=db_name(rsc_dbid),rsc_objid
     84  from master..syslockinfo where rsc_type in(4,5)
     85 open tb
     86 fetch next from tb into @rid,@dbname,@id
     87 while @@fetch_status=0
     88 begin
     89  set @s='select @objname=name from ['+@dbname+']..sysobjects where id=@id'
     90  exec sp_executesql @s,N'@objname sysname out,@id int',@objname out,@id
     91  insert into #t values(@rid,@objname)
     92  fetch next from tb into @rid,@dbname,@id
     93 end
     94 close tb
     95 deallocate tb
     96 select 进程id=a.req_spid
     97  ,数据库=db_name(rsc_dbid)
     98  ,类型=case rsc_type when 1 then 'NULL 资源(未使用)'
     99   when 2 then '数据库'
    100   when 3 then '文件'
    101   when 4 then '索引'
    102   when 5 then ''
    103   when 6 then ''
    104   when 7 then ''
    105   when 8 then '扩展盘区'
    106   when 9 then 'RID(行 ID)'
    107   when 10 then '应用程序'
    108  end
    109  ,对象id=rsc_objid
    110  ,对象名=b.obj_name
    111  ,rsc_indid
    112  from master..syslockinfo a left join #t b on a.req_spid=b.req_spid
    113 go
    114 drop table #t
  • 相关阅读:
    帝国 标签模板 使用程序代码 去除html标记 并 截取字符串
    iis6 伪静态 iis配置方法 【图解】
    您来自的链接不存在 帝国CMS
    帝国cms Warning: Cannot modify header information headers already sent by...错误【解决方法】
    .fr域名注册 51元注册.fr域名
    帝国网站管理系统 恢复栏目目录 建立目录不成功!请检查目录权限 Godaddy Windows 主机
    星外虚拟主机管理平台 开通数据库 出现Microsoft OLE DB Provider for SQL Server 错误 '8004' 从字符串向 datetime 转换失败
    ASP.NET 自定义控件学习研究
    CSS层叠样式表之CSS解析机制的优先级
    ASP.NET程序员工作面试网络收藏夹
  • 原文地址:https://www.cnblogs.com/w-zoe/p/9011064.html
Copyright © 2020-2023  润新知