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

摘要:
Sys.SysProcesses系统表是一个很重要的系统视图,主要用来定位与解决SqlServer的阻塞和死锁视图中主要的字段:1.Spid:SqlServr会话ID2.Kpid:Windows线程ID3.Blocked:正在阻塞求情的会话ID。对于系统进程,将存储SqlServer的启动时间10.Open_tran:进程的打开事务个数。SQLServer自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁,但没有这里介绍的方法好用。

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阻塞进程正在执行的操作

frommaster..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

SELECTspid,
         blocked,
         DB_NAME(sp.dbid) ASDBName,
         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) ELSEsp.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) ASA
WHERE    spid > 50
ORDER BY blocked DESC, DB_NAME(sp.dbid) ASC, a.[text];

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

查询死锁进程语句

selectrequest_session_id spid,
OBJECT_NAME(resource_associated_entity_id) tableName
fromsys.dm_tran_locks
whereresource_type='OBJECT'

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

--检测死锁

--如果发生死锁了,我们怎么去检测具体发生死锁的是哪条SQL语句或存储过程?

--这时我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句。SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。

usemaster

go

create proceduresp_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 '现在没有阻塞和死锁信息' asmessage

--循环开始

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

--杀死锁和进程

--如何去手动的杀死进程和锁?最简单的办法,重新启动服务。但是这里要介绍一个存储过程,通过显式的调用,可以杀死进程和锁。

usemaster

go

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[p_killspid]

GO

create procp_killspid

@dbname varchar(200) --要关闭进程的数据库名

as

 declare @sql nvarchar(500)

 declare @spid nvarchar(20)

 declare #tb cursor for

  select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)

 open#tb

 fetch next from #tb into @spid

 while @@fetch_status=0

 begin

  exec('kill '+@spid)

  fetch next from #tb into @spid

 end

 close#tb

 deallocate#tb

go

--用法

exec p_killspid 'newdbpy'

--查看锁信息

--如何查看系统中所有锁的详细信息?在企业管理管理器中,我们可以看到一些进程和锁的信息,这里介绍另外一种方法。

--查看锁信息

create table #t(req_spid int,obj_name sysname)

declare @s nvarchar(4000)

 ,@rid int,@dbname sysname,@id int,@objnamesysname

declare tb cursor for

 select distinct req_spid,dbname=db_name(rsc_dbid),rsc_objid

 from master..syslockinfo where rsc_type in(4,5)

opentb

fetch next from tb into @rid,@dbname,@id

while @@fetch_status=0

begin

 set @s='select @objname=name from ['+@dbname+']..sysobjects where id=@id'

 exec sp_executesql @s,N'@objname sysname out,@id int',@objname out,@id

 insert into #t values(@rid,@objname)

 fetch next from tb into @rid,@dbname,@id

end

closetb

deallocatetb

select 进程id=a.req_spid

 ,数据库=db_name(rsc_dbid)

 ,类型=case rsc_type when 1 then 'NULL 资源(未使用)'

  when 2 then '数据库'

  when 3 then '文件'

  when 4 then '索引'

  when 5 then ''

  when 6 then ''

  when 7 then ''

  when 8 then '扩展盘区'

  when 9 then 'RID(行 ID)'

  when 10 then '应用程序'

 end
 ,对象id=rsc_objid

 ,对象名=b.obj_name

 ,rsc_indid

 from master..syslockinfo a left join #t b on a.req_spid=b.req_spid

go

drop table #t

--查看还未提交的事务的SQL语句

USEmaster

GO

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT es.session_id, es.login_name, es.host_name, est.text
  , cn.last_read, cn.last_write, es.program_name

FROMsys.dm_exec_sessions es

INNER JOIN sys.dm_tran_session_transactions st --系统里还存在的事务

            ON es.session_id =st.session_id

INNER JOINsys.dm_exec_connections cn

            ON es.session_id =cn.session_id

CROSSAPPLY sys.dm_exec_sql_text(cn.most_recent_sql_handle) est

LEFT OUTER JOINsys.dm_exec_requests er                   

            ON st.session_id =er.session_id

                AND er.session_id IS NULL

 

查看被锁的表

select   request_session_id   spid,OBJECT_NAME(resource_associated_entity_id) tableName  

from   sys.dm_tran_locks where resource_type='OBJECT'

免责声明:文章转载自《利用sys.sysprocesses检查SqlServer的阻塞和死锁》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Swoole从入门到入土(17)——WebSocket服务器[成员函数与配置选项]svn 删除、移动和改名下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SQL语句查询每个分组的前N条记录的实现方法

SQL语句查询每个分组的前N条记录的实现方法: 1、生成测试数据: #T if object_id('tempdb.dbo.#T') is not null drop table #T; create table #T (ID varchar(3), GID int, Author varchar(29), Title varchar(39), Da...

sql-优化建议

1. 查询 SQL 尽量不要使用 select *,而是 select 具体字段 反例: select * from employee; 正例: select id,name from employee; 理由: 只取需要的字段,节省资源、减少网络开销; select * 进行查询时,很可能就不会使用到覆盖索引了,就会造成回表查询。 2. 如果知道...

rownum与rowId

  一、RowNum      Rownum是oracle生成结果集时得到的一个伪列, 按照读出行的顺序, 第一条rownum=1, 第二条=2.      对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<、<=、!=),并非说用>,>=,=,be...

SqlServer timestamp数据类型

--时间戳类型和bigint互相转化示例:  set nocount on  --申明3个时间戳  declare @timeFlag1 bigint  declare @timeFlag2 bigint  declare @timeFlag3 bigint  --建立表,timestamp类型不需要字段名  create table test(times...

Mybatis之collection与association标签

collection与association标签的功能就是为了解决查询条件映射到一个类或一个集合上,适用于对于多对一,一对多的映射结果,现在我们就探究其具体使用吧。 环境搭建: 数据库搭建 CREATE TABLEteacher ( id INT(10) NOT NULL, name VARCHAR(30) DEFAULT NULL, PRI...

Oracle中索引的使用 索引性能优化调整

索引是由Oracle维护的可选结构,为数据提供快速的访问。准确地判断在什么地方需要使用索引是困难的,使用索引有利于调节检索速度。 当建立一个索引时,必须指定用于跟踪的表名以及一个或多个表列。一旦建立了索引,在用户表中建立、更改和删除数据库时, Oracle就自动地维护索引。创建索引时,下列准则将帮助用户做出决定:        1) 索引应该在SQL语句的...