在SQL Server中如何监控被长时间阻塞的存储过程

千强大大_3714

千强大大_3714

2026-10-25

545人浏览

原创

应优先查 sys.dm_exec_requests 中 blocking_session_id > 0 的会话,因其标识持锁未被阻塞的源头;该字段仅在 requests 视图中存在,需联查 sessions 和 sql_text 定位语句,配合 blocked process threshold + xevent 实现自动捕获与安全 kill。

在sql server中如何监控被长时间阻塞的存储过程

查 blocking_session_id > 0 的会话,不是看 login_time

很多人一上来就查 sys.dm_exec_sessions 里 login_time 超过 30 分钟的会话,然后 KILL——这大概率误杀。真正该盯的是阻塞链顶端:谁在持锁不放、且没被别人阻塞?关键字段是 blocking_session_id。

必须联查 sys.dm_exec_requests,因为只有它暴露实时阻塞关系。单独查 sys.dm_exec_sessions 拿不到 blocking_session_id 值(该字段只在 requests 视图中存在)。

  • blocking_session_id > 0:该会话正在阻塞别人,且自身未被阻塞 → 优先 kill 目标
  • blocking_session_id = -2:已被 SQL Server 选为死锁牺牲品,但尚未终止 → 必须 kill,否则可能卡住资源释放
  • status = 'sleeping' 且 last_request_end_time 很旧:仅说明空闲,不等于有害;得结合 sys.dm_tran_locks 确认是否还持有锁

用 sp_who2 或自定义查询定位阻塞源头和 SQL 文本

sp_who2 active 能快速看到 BlkBy 列,但它不返回 SQL 语句。真要定位到哪句存储过程里的 UPDATE 卡住了,得手动关联 sys.dm_exec_sql_text。

以下查询能同时拿到阻塞者、被阻塞者、各自执行的 SQL 片段、等待时长、客户端 IP:

SELECT 
  r.session_id,
  r.blocking_session_id,
  r.total_elapsed_time / 1000.0 AS [wait_sec],
  s.host_name,
  s.program_name,
  s.client_net_address,
  t.text AS [sql_text],
  SUBSTRING(t.text, r.statement_start_offset/2 + 1,
    (CASE WHEN r.statement_end_offset = -1 
      THEN LEN(CONVERT(NVARCHAR(MAX), t.text)) * 2 
      ELSE r.statement_end_offset END - r.statement_start_offset) / 2 + 1) AS [current_statement]
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id  0 
  AND r.session_id > 50 
  AND r.session_id  @@SPID;

注意:statement_start_offset 和 statement_end_offset 是字节偏移,除以 2 才对应 Unicode 字符位置;text 可能为空(比如用了加密存储过程或权限不足),需提前校验。

设置 blocked process threshold + Extended Events 捕获长期阻塞

靠人工轮询 DMV 是下策。SQL Server 提供了轻量级机制:blocked process threshold (s) 配置项,配合 system_health 默认 session 或自定义 XEvent 捕获阻塞事件。

秒言AI语音输入法
秒言AI语音输入法

秒言AI语音输入法是一款AI音频处理工具,AI语音输入工具,极速响应、精准识别。

下载

启用方式(需 sysadmin 权限):

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'blocked process threshold (s)', 5; -- 阻塞超 5 秒即触发报告
RECONFIGURE;

之后,阻塞达到阈值时,SQL Server 会生成 blocked_process_report 事件,包含完整 XML 报告,含 <blocking-process></blocking-process> 和 <blocked-process></blocked-process> 两块结构,可直接解析出阻塞者 SPID、SQL、等待资源类型(如 KEY、OBJECT)、甚至事务开始时间。

  • 别用 SQL Trace 或 Profiler 长期跑,开销大、易拖慢实例
  • 默认 system_health 已捕获该事件,但只保留最近 1 小时左右;如需归档,建独立 XEvent session 并写入文件目标
  • XML 中 waittime 单位是毫秒,resource_description 如 KEY:13:72057595528151040(f2008a1296d8) 表示具体索引键,可用于反查表和索引

KILL 之前必须验证 is_user_process 和当前无活跃请求

直接 KILL @spid 风险极高。系统会话(如 LAZY WRITER、CHECKPOINT)若被误杀,可能导致 checkpoint 失败或缓存刷盘异常。

安全 kill 的三步检查:

  • 查 sys.dm_exec_sessions.is_user_process = 1,排除系统会话
  • 确认该 SPID 在 sys.dm_exec_requests 中不存在活跃记录(即没正在执行语句),或虽存在但 blocking_session_id = -2
  • 用参数化方式执行 KILL:EXEC sys.sp_executesql N'KILL @p1', N'@p1 int', @p1 = @spid,避免字符串拼接注入和类型转换失败

务必加 TRY...CATCH,捕获 Msg 6103(会话已断开)、Msg 1205(死锁牺牲品已结束)等非致命错误,防止存储过程因单个 KILL 失败而中断后续逻辑。

最常被忽略的一点:阻塞未必来自存储过程本身,可能是它调用的另一个未提交事务、或嵌套的动态 SQL 持有锁后异常退出未回滚。所以 kill 后还得查 sys.dm_tran_active_transactions 和 sys.dm_tran_session_transactions,确认锁是否真正释放。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

存储过程

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

5851

4

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2023.06.29

2825

3

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2023.08.14

4001

10

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2023.08.31

3131

3

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.05

987

5

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.09

2747

5

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

2023.10.16

2747

4

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

2023.10.16

2913

3

vb连接数据库的方法
vb连接数据库的方法

vb连接数据库的方法有使用ADO对象库、使用OLEDB数据提供程序、使用ODBC数据源等。详细介绍:1、使用ADO对象库方法,ADO是一种用于访问数据库的COM组件,可以通过ADO连接数据库并执行SQL语句。可以使用ADODB.Connection对象来建立与数据库的连接,然后使用ADODB.Recordset对象来执行查询和操作数据;2、使用OLEDB数据提供程序方法等等。

2023.10.19

2561

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
布尔教育燕十八mysql高级视频教程
布尔教育燕十八mysql高级视频教程

共24课时 | 8.6万人学习

魔乐科技oracle视频教程
魔乐科技oracle视频教程

共27课时 | 6.7万人学习

肖文吉Oracle视频教程
肖文吉Oracle视频教程

共33课时 | 9.1万人学习