我在死锁上做一个sql server profiler,因为用户正在查询超时。在分析器中,eventClass列显示Lock:Escalation和Lock:Cancel。如何找出导致查询被取消的原因?基本上相同的查询是由一堆用户运行的,事情可以直接缩放,但是一整天用户都会关机。我也运行sqldiag;然而,不幸的是,我不是DBA,而是为了发现问题而糊里糊涂。有什么建议吗?
感谢社区 缺口
答案 0 :(得分:2)
查询超时和死锁几乎是互斥的。
死锁监视器后台线程将很快发现死锁情况并以一种方式处理死锁进程(通常是回滚成本较低的进程)将被选为死锁牺牲品< / em>它的工作直到回滚。
查询超时可能发生在活锁上,大量的cuncurrent进程试图访问相同的资源,从而阻塞彼此。当经过的时间超过超时值(由客户端设置)时,查询将被取消(这就是您在跟踪中看到Lock:Canceled事件的原因)。
客户端处理这种情况非常重要,因为只要连接处于活动状态或事务没有回滚,所有在超时事务中获取的资源将继续使用。
要诊断阻止情况,您可以做几件事。
如果您在进程被阻止时正好进行监控,请运行以下查询以找出阻止链的头部,以便您进一步调查:
select r.session_id, r.host_name, r.program_name,
r.login_name, r.nt_domain, r.nt_user_name,
r.total_elapsed_time/1000 as total_elapsed_time_sec, getdate() as vrijeme,
(select text from sys.dm_exec_sql_text(c.most_recent_sql_handle)) as sql_text
from sys.dm_exec_connections c
inner join sys.dm_exec_sessions r on r.session_id = c.session_id
where r.is_user_process = 1
and exists (
select *
from sys.dm_os_waiting_tasks r2
where r2.blocking_session_id = r.session_id
)
and not exists (
select *
from sys.dm_os_waiting_tasks r3
where r3.session_id = r.session_id
)
and r.total_elapsed_time/1000 > 10
此查询的阈值为10秒。
此外,您可以使用Profiler捕获阻止进程事件,然后再对其进行分析。请查看此链接以获取详细说明:
https://www.simple-talk.com/sql/sql-tools/how-to-identify-blocking-problems-with-sql-profiler/
通常会有少数查询负责绝大多数阻止。识别它们并尝试优化它们(重写,索引......)。此外,您可以为数据库设置读提交的快照隔离级别,以避免读者等待编写者。