MSSQL如何确定死锁根源session_id?

MSSQL 2016每几天死锁一次。

执行:

SELECT sqltext.text,
       req.session_id,
       req.status,
       req.command,
       req.cpu_time,
       req.total_elapsed_time,
       req.blocking_session_id
FROM sys.dm_exec_requests req (NOLOCK)
    CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS sqltext

通过blocking_session_id 发现阻塞session最终矛头都指向是session 134。
但是session 134的状态是suspended,正常不是应该状态是running才可能是阻塞根源的session吗?

再去找找134信息

SELECT *
FROM sys.dm_exec_requests
WHERE session_id = 134;


【以下回答由 GPT 生成】

首先,我们需要理解一些关于死锁的基本概念。

死锁是指两个或多个事务在互相等待对方释放资源时,永远无法继续执行的情况。在MSSQL数据库中,当发生死锁时,系统会自动选择一个会话作为死锁的牺牲者(victim),将其终止以解开死锁。

在你提供的查询结果中,会话ID为134的会话被标记为"blocking_session_id",这意味着该会话正在阻塞其他会话。然而,由于该会话的状态为"suspended",这可能意味着它当前没有活跃的任务在执行。

为了确定造成死锁的根源会话,我们可以使用系统视图sys.dm_tran_locks。它包含有关数据库中当前会话的锁定信息。下面是一种可能的解决方案:

  1. 使用以下查询来查找死锁的信息:
SELECT dl1.request_session_id AS victim_session_id,
       dl1.resource_type AS victim_resource_type,
       OBJECT_NAME(dl1.resource_associated_entity_id) AS victim_entity,
       dl2.request_session_id AS blocking_session_id,
       dl2.resource_type AS blocking_resource_type,
       OBJECT_NAME(dl2.resource_associated_entity_id) AS blocking_entity,
       dl2.request_mode AS blocking_mode
FROM sys.dm_tran_locks dl1
JOIN sys.dm_tran_locks dl2 ON dl1.resource_type = dl2.resource_type
    AND dl1.resource_associated_entity_id = dl2.resource_associated_entity_id
WHERE dl1.request_session_id = 134 -- 死锁的牺牲者会话ID
  AND dl2.request_session_id <> 134 -- 排除牺牲者会话ID
  1. 通过以上查询,我们可以得到死锁的根源会话的会话ID和相关信息。

需要注意的是,死锁信息可能会在系统重新启动或长时间运行后被清除。因此,最好将查询集成到你的监控系统或周期性作业中,以捕获死锁发生时的相关信息。

如果以上方法无法帮助你确定造成死锁的根源会话,可能涉及更复杂的情况。在这种情况下,建议你联系MSSQL专家以获取进一步的支持和调试。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^