sql server 2022 中无法通过视图实时监控死锁和阻塞,死锁需依赖扩展事件(如 system_health 中的 xml_deadlock_report),阻塞需周期性轮询 sys.dm_exec_requests 和 sys.dm_tran_locks 并结合上下文分析。

SQL Server 2022 中无法直接通过「视图」实时监控死锁和阻塞——系统视图只提供快照,死锁事件本身必须靠扩展事件(XEvent)捕获,而阻塞需结合 sys.dm_exec_requests 和 sys.dm_tran_locks 主动轮询分析。
死锁信息不能只靠 sys.dm_exec_requests 或 sys.dm_os_waiting_tasks
这两个 DMV 只反映「当前等待状态」,死锁一旦发生并被引擎解除,相关会话通常已回滚或终止,其记录在 sys.dm_exec_requests 中迅速消失;sys.dm_os_waiting_tasks 也不保留历史死锁链。你看到的往往是“事后真空”。
- 死锁图(deadlock graph)只存在于扩展事件会话、trace flag 1222 日志或 SQL Server 错误日志中(后者默认不启用)
-
sys.dm_exec_sessions和sys.dm_exec_connections不包含死锁上下文 - 试图用
SELECT * FROM sys.dm_exec_requests WHERE blocking_session_id > 0查死锁,大概率查不到——因为死锁检测器已强制 Kill 其中一个会话
必须启用扩展事件来捕获真实死锁图
SQL Server 2022 自带预定义的 system_health 扩展事件会话,默认启用,并且已包含 xml_deadlock_report 事件(保留最近 4 小时左右,取决于环形缓冲区压力)。这是最轻量、最可靠的死锁来源。
- 查看最近死锁:执行
SELECT CAST(target_data AS XML) FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE s.name = 'system_health',然后定位<event name="xml_deadlock_report"></event>节点 - 若需长期留存,建议新建专用 XEvent 会话,把
xml_deadlock_report输出到文件目标(event_file),并配置自动滚动 - 不要依赖
sp_who2或sp_lock——它们在 2022 中已过时,且不输出死锁结构
阻塞链需要组合查询多个 DMV 并注意时间窗口
阻塞是动态过程,单次查询只能抓取某一毫秒的状态。要识别“持续阻塞”,得周期性采样并比对 blocking_session_id 和 wait_time 变化。
- 核心查询模式:
SELECT r.session_id, r.blocking_session_id, r.wait_type, r.wait_time, t.text FROM sys.dm_exec_requests r OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) t WHERE r.blocking_session_id > 0 OR r.session_id IN (SELECT blocking_session_id FROM sys.dm_exec_requests WHERE blocking_session_id > 0) - 务必 JOIN
sys.dm_exec_sessions获取 login_name 和 host_name,否则无法定位业务方 -
sys.dm_tran_locks中的request_status = 'WAIT'行才代表真正被阻塞的锁请求;request_status = 'GRANT'是正常持有者 - 避免在高并发 OLTP 上高频轮询(如每秒一次)——DMV 查询本身可能加剧阻塞
别把「视图」当监控入口,而是用它做聚合展示层
你可以创建一个自定义视图(比如 v_blocking_summary)封装上述阻塞查询逻辑,但它只是简化调用,不解决采集时效性问题。真正的监控闭环必须由外部工具或 Agent 作业驱动。
- 示例视图定义中,
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle)必须加WHERE r.sql_handle IS NOT NULL条件,否则遇到空 handle 会报错 - 视图里不能包含非确定性函数(如
GETDATE()),所以无法在视图内实现“过去 5 分钟阻塞趋势” - 如果想看历史阻塞,得依赖 Query Store 的
sys.query_store_wait_stats(需提前开启 Query Store 并设置合适捕获策略)
死锁图的 XML 结构嵌套深、字段多,人工解析成本高;而阻塞链的“根因会话”常隐藏在多层嵌套中(比如 A 阻塞 B,B 阻塞 C,但 A 拿着锁不释放是因为它在等一个网络延迟的 Linked Server 查询)。这两类问题,永远不是建个视图就能看清的——关键在采集时机、上下文完整性和后续解析能力。











