如何通过SQL存储过程监控长连接并自动杀掉死锁进程?

风强同学_7504

风强同学_7504

2026-07-05

789人浏览

原创

sql server 本身不提供“自动杀死长连接”的内置机制,但可通过组合 sys.dm_exec_sessions、sys.dm_exec_requests 和 sys.dm_tran_locks 视图,配合定时作业与存储过程,实现对长时间空闲连接或死锁会话(blocking_session_id = -2)的识别与终止;核心依据是阻塞关系而非连接时长,真正该 kill 的是阻塞源头(blocking_session_id > 0)或已标记的死锁牺牲品。

如何通过sql存储过程监控长连接并自动杀掉死锁进程?

直接上结论:SQL Server 本身不提供“自动杀死长连接”的内置机制,但可以通过组合 sys.dm_exec_sessions、sys.dm_exec_requests 和 sys.dm_tran_locks 视图,配合定时作业 + 存储过程,实现对**长时间空闲连接(Idle)** 或 **已确认死锁的会话(blocking_session_id = -2)** 的识别与终止。关键不是“长连接”本身有问题,而是它可能持有锁却不释放——真正要杀的是**阻塞源头**或**死锁牺牲品**。

怎么查出真正该 kill 的会话(不是看 login_time,而是看 blocking_session_id)

很多人误以为“连接时间久=该杀”,其实错的。SQL Server 中判断是否该干预,核心依据是等待链和死锁标识:

  • blocking_session_id = -2 表示该会话是 SQL Server 自动选中的死锁牺牲品(已被标记,但尚未被 KILL),这是最明确的 kill 信号
  • blocking_session_id > 0 表示该会话正在阻塞别人,且自身没有被更高层阻塞 —— 这才是真正的“阻塞源头”,优先 kill 它
  • status = 'sleeping' 且 last_request_end_time 距今超过阈值(比如 30 分钟),才说明是空闲连接;但仅 sleep 不等于有害,除非它还持有锁(需关联 sys.dm_tran_locks 验证)
  • 别只查 sysprocesses(已弃用),必须用 sys.dm_exec_sessions + sys.dm_exec_requests 联查,否则拿不到准确 blocking 关系

存储过程里怎么安全地 kill,避免误杀或权限失败

直接拼接 KILL @spid 很危险,必须加三层防护:

codex-cn-bridge
codex-cn-bridge

一款AI工具,主要用于通过协议转换与自动配置,使 OpenAI Codex CLI 支持多家国内 AI 模型提供商,适合需要提升相关任务效率的用户。

下载
  • 先查 sys.dm_exec_sessions 确认 is_user_process = 1,排除系统会话(如 LAZY WRITER、CHECKPOINT)
  • 再查 sys.dm_exec_requests 确认该会话当前没有活跃请求(session_id 不在结果集中),或虽有请求但 blocking_session_id = -2
  • 执行 KILL 前加 TRY...CATCH,捕获 Msg 1205(死锁牺牲品已结束)、Msg 6103(会话不存在)等常见错误,避免存储过程中断
  • 不要用 EXEC('KILL '+@spid),改用 EXEC sys.sp_executesql N'KILL @p1', N'@p1 int', @p1 = @spid,防止注入和类型转换问题

为什么定时作业比触发器更靠谱

SQL Server 没有“死锁发生时触发”的原生事件,traceflag 1222 或 Extended Events 只能记录死锁图,不能直接触发 KILL。所以实际落地只能靠轮询:

  • 用 SQL Server Agent 创建作业,每 30 秒跑一次存储过程(太频繁会增加系统负担,太慢则业务已卡住)
  • 作业步骤用 T-SQL,不是 PowerShell 或 CmdExec,避免权限跨上下文问题
  • 作业运行账户必须有 VIEW SERVER STATE 和 ALTER ANY DATABASE(或至少目标 DB 的 db_owner),否则查不到会话或 KILL 权限不足
  • 千万别用 sp_who_lock 这类老式存储过程(依赖已废弃的 sysprocesses),它在 SQL Server 2016+ 上可能漏掉新会话或返回错误 blocking 关系

最容易被忽略的兼容性坑:SQL Server 版本差异

同一个查询,在不同版本行为可能完全不同:

  • sys.dm_exec_sessions.last_request_end_time 在 SQL Server 2005+ 才可用,2000 必须用 login_time + 估算,极不可靠
  • blocking_session_id = -2 是 SQL Server 2005 引入的死锁标识,2000 只能靠 sysprocesses.blocked = 0 AND spid IN (SELECT blocked FROM sysprocesses) 推断,逻辑复杂且易误判
  • sys.dm_tran_locks 的 resource_description 字段在 2012+ 才支持解析页锁/键锁细节,旧版只能看到模糊资源名
  • 如果你还在用 SQL Server 2000,别折腾存储过程自动 kill —— 直接升级,或者用 Windows 计划任务调 osql -E -Q "exec sp_killlock 1" 更现实

真正难的不是写 kill 逻辑,而是区分“该杀的阻塞源头”和“不该动的长事务”。一个未提交的银行转账事务跑了 5 分钟,和一个忘记 commit 的测试脚本挂了 2 小时,表现一样但处置方式相反。监控脚本里必须留人工干预开关(比如加参数 @dry_run = 1),上线前务必在非生产环境用真实阻塞场景压测验证。

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

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

下载

相关标签:

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

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3943

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

851

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1029

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5781

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2723

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5760

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7641

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1050

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

912

5

热门下载

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

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习