在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,肯定web服务器无端障后。就须要检查数据库是否有出现阻塞html
当时数据库的生产环境中主表数据量超过2000w,子表数据量超过1亿,且更新和新增频繁。再加上作了同步镜像,很消耗资源。web
这时就要新建一个会话,大概须要了解如下几点:sql
1.当前活动会话量有多少?数据库
2.会话运行时间?浏览器
3.会话之间有没有阻塞?服务器
4.阻塞时间 ?session
查询阻塞的方法有不少。有sql 2000 的sp_lock, 有sql 2005及以上的dmv并发
一. 阻塞查询 sp_lock函数
执行 exec sp_lock 下面列下关键字段oop
spid 是指进程ID,这个过滤掉了系统进程,只展现了用户进程spid>50。
dbid 指当前实例下的哪一个数据库 , 使用DB_NAME() 函数来标识数据库
type 请求锁住的模式
mode 锁的请求状态
GRANT:已获取锁。
CNVRT:锁正在从另外一种模式进行转换,可是转换被另外一个持有锁(模式相冲突)的进程阻塞。
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
1 SELECT 2 spid, 3 kpid, 4 blocked, 5 waittime AS 'waitms', 6 lastwaittype, 7 DB_NAME(dbid)AS DB, 8 waitresource, 9 open_tran, 10 hostname,[program_name], 11 hostprocess,loginame, 12 [status] 13 FROM sys.sysprocesses WITH(NOLOCK) 14 WHERE kpid>0 AND [status]<>'sleeping' AND spid>50
sys.sysprocesses 能显示会话进程有多少, 等待时间, open_tran有多少事务, 阻塞会话是多少. 总体内容更为详细。
关键字段说明:
spid 会话ID(进程ID),SQL内部对一个链接的编号,通常来说小于50
kipid 线程ID
blocked: 阻塞的进程ID, 值大于0表示阻塞, 值为自己进程ID表示io操做
waittime:当前等待时间(以毫秒为单位)。
open_tran: 进程的打开事务数
hostname:创建链接的客户端工做站的名称
program_name 应用程序的名称。
hostprocess 工做站进程 ID 号。
loginame 登陆名。
[status]
running = 会话正在运行一个或多个批
background = 会话正在运行一个后台任务,例如死锁检测
rollback = 会话具备正在处理的事务回滚
pending = 会话正在等待工做线程变为可用
runnable = 会话中的任务在等待,由scheduler来运行的可执行队列中。(重要)
spinloop = 会话中的任务正在等待调节锁变为可用。
suspended = 会话正在等待事件(如 I/O)完成。(重要)
sleeping = 链接空闲
wait resource 格式为 fileid:pagenumber:rid 如(5:1:8235440)
kpid=0, waittime=0 空闲链接
kpid>0, waittime=0 运行状态
kpid>0, waittime>0 须要等待某个资源,才能继续执行,通常会是suspended(等待io)
kpid=0, waittime=0 但它仍是阻塞的源头,查看open_tran>0 事务没有及时提交。
若是blocked>0,但waittime时间很短,说明阻塞时间不长,不严重 若是status 上有好几个runnable状态任务,须要认真对待。 cpu负荷太重没有及时处理用户的并发请求