利用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进程死锁的语句 查询死锁进程语句 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran_locks where resource_type=‘OBJECT‘ ? ? ?下面再给大家分享一段关于sqlserver检测死锁;杀死锁和进程;查看锁信息 --检测死锁 --如果发生死锁了,我们怎么去检测具体发生死锁的是哪条SQL语句或存储过程? --这时我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句。SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁,但没有这里介绍的方法好用。 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 ? --杀死锁和进程 --如何去手动的杀死进程和锁?最简单的办法,重新启动服务。但是这里要介绍一个存储过程,通过显式的调用,可以杀死进程和锁。 use master 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 proc p_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,@objname sysname declare tb cursor for select distinct req_spid,dbname=db_name(rsc_dbid),rsc_objid from master..syslockinfo where rsc_type in(4,5) open tb fetch next from tb into @rid,@dbname,@id while @@fetch_status=0 begin set @s=‘select @objname=name from [‘+@dbname+‘]..sysobjects where [email?protected]‘ 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,@id end close tb deallocate tb 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语句 USE master 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 FROM sys.dm_exec_sessions es INNER JOIN sys.dm_tran_session_transactions st --系统里还存在的事务 ON es.session_id = st.session_id INNER JOIN sys.dm_exec_connections cn ON es.session_id = cn.session_id CROSS APPLY sys.dm_exec_sql_text(cn.most_recent_sql_handle) est LEFT OUTER JOIN sys.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‘ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |