sql server中真正该kill的会话取决于blocking_session_id:值为-2表示已被选为死锁牺牲品,需立即处理;大于0表示是阻塞源头,应优先kill;仅当status='sleeping'且last_request_end_time超阈值并持有锁时,才考虑kill空闲连接。

SQL Server 中怎么识别真正该 kill 的会话
别只看 login_time 或连接时长,SQL Server 里“长连接”本身不危险,危险的是它是否正在阻塞别人、或已被标记为死锁牺牲品。关键字段是 blocking_session_id:
-
blocking_session_id = -2:该会话已被 SQL Server 选为死锁牺牲品,正在等待被 KILL,必须立即处理 -
blocking_session_id > 0:它是当前阻塞链的源头,优先 kill 它才能解围 -
status = 'sleeping'且last_request_end_time超过阈值(比如 30 分钟),再结合sys.dm_tran_locks确认它还持有锁,才说明是“空闲但有害”的连接
必须用 sys.dm_exec_sessions 和 sys.dm_exec_requests 联查,sysprocesses 已弃用,查不到准确阻塞关系。
MySQL 中 KILL QUERY 和 KILL CONNECTION 怎么选
应用层用了连接池(如 HikariCP、Druid)时,KILL CONNECTION 很容易触发“Communications link failure”,因为连接突然断开,池子来不及清理。这时候应优先用 KILL QUERY:
-
KILL QUERY <code>id:只中断当前语句,连接保持打开,适合误执行的 SELECT 或 UPDATE -
KILL CONNECTION <code>id(等价于KILL <code>id):终止整个连接,适合客户端崩溃后残留的 Sleep 连接,或KILL QUERY失效的 DDL 场景(如ALTER TABLE) -
INFO字段可能被截断(默认 1024 字符),查不到完整 SQL 时,加SHOW FULL PROCESSLIST;云数据库(如阿里云 RDS)常屏蔽该视图,得改用控制台“实时会话”功能
PostgreSQL 用 pg_cancel_backend 还是 pg_terminate_backend
两者信号级别不同:pg_cancel_backend 发 SIGINT(类似 Ctrl+C),只取消当前查询,事务不回滚,连接不断;pg_terminate_backend 发 SIGTERM,强制断连并回滚整个事务。实际选择看状态:
- 状态是
active且能确认只是慢查询?用pg_cancel_backend(<code>pid),保留连接复用 - 状态是
idle in transaction?必须用pg_terminate_backend(<code>pid),否则锁一直挂着,其他会话全被堵住 - 执行后返回
false,常见原因是 PID 不存在,或你没pg_signal_backend角色权限——别硬 retry,先查pg_stat_activity确认目标还在不在
所有数据库里最易被忽略的安全细节
kill 不是发完命令就完事了。真正难处理的是后续状态和资源释放:
- MySQL 执行
KILL后状态变成Killed,不代表立刻结束——大事务回滚可能持续几十秒,期间仍占 CPU 和锁 - SQL Server 的
KILL必须配合TRYCATCH捕获Msg 1205(死锁已结束)、Msg 6103(会话不存在),否则存储过程直接报错中断 - PostgreSQL 的
pg_terminate_backend触发回滚,但回滚耗时取决于事务修改量,监控要看pg_stat_activity.backend_start和state_change时间差,不是只盯query_start
杀会话只是止血,不是根治。背后锁争用、统计信息陈旧、参数嗅探导致的执行计划错误,才是反复出现长会话的真正原因。










