在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,确定web服务器无故障后。就需要检查数据库是否有出现阻塞

当时数据库的生产环境中主表数据量超过2000w,子表数据量超过1亿,且更新和新增频繁。再加上做了同步镜像,很消耗资源。

这时就要新建一个会话,大概需要了解以下几点:

1.当前活动会话量有多少?

2.会话运行时间?

3.会话之间有没有阻塞?

4.阻塞时间 ?

查询阻塞的方法有很多。有sql 2000 的sp_lock, 有sql 2005及以上的dmv

一. 阻塞查询 sp_lock

      执行 exec sp_lock  下面列下关键字段

      spid 是指进程ID,这个过滤掉了系统进程,只展示了用户进程spid>50。

      dbid 指当前实例下的哪个数据库 , 使用DB_NAME() 函数来标识数据库

      type 请求锁住的模式

      mode 锁的请求状态

                     GRANT:已获取锁。

                     WAIT:锁被另一个持有锁(模式相冲突)的进程阻塞。

     总结:当mode 不为GRANT状态时, 需要了解当前锁的模式,以及通过进程ID查找当前sql 语句 

                例如当前进程ID是416,且mode状态为WAIT 时,查看方式 DBCC INPUTBUFFER(416)

               用sp_lock查询显示的信息量很少,也很难看出谁被谁阻塞。所以当数据库版本为2005及以上时不建议使用。

 二.阻塞查询  dm_tran_locks         

 1 SELECT 
 2 t1.resource_type,
 3 t1.resource_database_id,
 4 t1.resource_associated_entity_id,
 5 t1.request_mode,
 6 t1.request_session_id,
 7 t2.blocking_session_id
 8 FROM sys.dm_tran_locks as t1
 9 INNER JOIN sys.dm_os_waiting_tasks as t2
10 ON t1.lock_owner_address = t2.resource_address;

     上面查询只显示有阻塞的会话, 关注blocking_session_id 也就是被阻塞的会话ID,同样使用DBCC INPUTBUFFER来查询sql语句

三.阻塞查询 sys.sysprocesses

 SELECT 
 spid,
 kpid,
 blocked,
 waittime AS 'waitms', 
 lastwaittype, 
 DB_NAME(dbid)AS DB,  
 waitresource, 
 open_tran,
 hostname,[program_name],
 hostprocess,loginame,
 [status]
 FROM sys.sysprocesses WITH(NOLOCK) 
 WHERE    kpid>0  AND  [status]<>'sleeping'  AND spid>50
 AND spid<>@@SPID
View Code

相关文章: