And*_*dén 3 sql-server deadlock
我正在尝试使用此查询从 sql-server 获取死锁信息
select XEventData.XEvent.value('(data/value)[1]', 'varchar(max)') as DeadlockGraph
FROM
(select CAST(target_data as xml) as TargetData
from sys.dm_xe_session_targets st
join sys.dm_xe_sessions s on s.address = st.event_session_address
where name = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
where XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'
Run Code Online (Sandbox Code Playgroud)
然而,查询需要永远并返回一个空结果。
为什么需要这么长时间,并且您从该视图中获得的死锁信息是否具有追溯力,以便我能够查明前段时间发生的死锁?
查询 XML 时必须非常小心。您的查询在这方面有点灾难,特别是这部分:where XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'
这导致一大堆 XML 被拖来拖去,加入,然后过滤:
使用exists方法会更好,如下所示:
SELECT
DeadlockGraph =
XEventData.XEvent.value('(data/value)[1]', 'varchar(max)')
FROM
(
SELECT
TargetData = CONVERT(xml, st.target_data)
FROM sys.dm_xe_session_targets AS st
JOIN sys.dm_xe_sessions AS s
ON s.address = st.event_session_address
WHERE s.name = 'system_health'
) AS Data
CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData(XEvent)
WHERE XEventData.XEvent.exist('/event/@name[ .= "xml_deadlock_report"]') = 1;
Run Code Online (Sandbox Code Playgroud)
XML 过滤仍然有点笨拙,但它在执行计划中发生得更早。
您可能还会发现首先将转换后的 XML 放入#temp
表中是有益的,这样 XML 结构的验证只需进行一次。
SELECT
TargetData =
CONVERT(xml, st.target_data)
INTO #x
FROM sys.dm_xe_session_targets AS st
JOIN sys.dm_xe_sessions AS s
ON s.address = st.event_session_address
WHERE s.name = 'system_health';
SELECT
DeadlockGraph =
XEventData.XEvent.value('(data/value)[1]', 'varchar(max)')
FROM
(
SELECT
TargetData
FROM #x
) AS Data
CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData(XEvent)
WHERE XEventData.XEvent.exist('/event/@name[ .= "xml_deadlock_report"]') = 1;
Run Code Online (Sandbox Code Playgroud)
如果您想要替代方案,您可能会发现sp_BlitzLock很有用。
只能靠运气了。数据的大小是有限制的,如果记录了很多事件,它们可能会推出有用的死锁数据。您可以编辑会话,正如Aaron Betrand 在此博客文章中所述。
如果您对死锁特别感兴趣,最好的办法是为此专门设置一个扩展的事件会话。
归档时间: |
|
查看次数: |
364 次 |
最近记录: |