如何在不到一秒钟的时间内跟踪发生的阻塞-SQL Server


14

我正在尝试解决不到一秒钟的阻塞问题。OLTP应用程序非常敏感,根据约定的SLA,某些事务的响应时间必须小于200ms。我们在新代码发行版中遇到了一些锁升级问题,可以通过减少更新中的批处理大小来解决这些问题。即使批处理量很小,我们也怀疑新sp阻塞了OLTP事务更新的同一行。

我需要找到被阻塞的会话及其等待的资源。根据我的理解,“阻塞的过程阈值”可以设置为至少1秒,因此这不会捕获阻塞。

我正在试验wait_info和wait_completed x事件。

还有其他方法可以跟踪此问题。谢谢


:就这么用相同的用户同样的问题stackoverflow.com/questions/38407021/...
TheGameiswar

Answers:


10

由于您对锁定而不是一般的锁定特别感兴趣,因此locks_lock_waits扩展事件听起来更合适。

开启过滤器 increment >= 200

CREATE EVENT SESSION [locks_lock_waits] ON SERVER 
ADD EVENT sqlserver.locks_lock_waits(
        ACTION(sqlserver.sql_text)
            WHERE  ( [sqlserver].[is_system] = 0
                     AND [increment] >= 200
                     AND [counter] <= 1000 ) 
    )
ADD TARGET package0.ring_buffer;

GO

ALTER EVENT SESSION [locks_lock_waits]  
ON SERVER  STATE = start;  

上面收集了等待锁定的语句达阈值的时间量,但未提供特定的锁定资源。

我从未使用过此事件,也没有深入了解此会话将在您的生产服务器上造成多少开销。

我找到了有关该主题的视频。强烈建议您进行过滤counter以减少收集的事件数量,而我在上面已经这样做了。

它还提到了一个旧的未记录的旧命令

dbcc lock(StallReportThreshold, 200) -- 200 is threshold in ms

哪个(如果启用了跟踪标志3605)将诸如以下内容的有限信息转储到SQL Server错误日志中。

进程53等待6844毫秒以获取RID上的S锁定:2:1:120:2结果:OKWAIT

我只是顺便提到了这一点,因为无论如何扩展事件显然是更可取的,因为它已被记录并且功能更强大。


我测试过locks_lock_waits,就像您说的那样,它没有资源信息。但是我不知道增量是时间。良好的信息dbcc锁,看上去很棒。您知道该信息可用多长时间后才能被转储到错误日志中。
jesijesi

抱歉,我没有说清楚。我问的是,我们要等多久才能运行dbcc lock命令。例如发生锁定,如果一个小时后我运行dbcc lock,我们是否仍能获取信息?
jesijesi

@jesijesi-今天之前我从未听说过它。我没有任何更多信息。我什至不知道要禁用它的参数。但是,您dbcc lock(StallReportThreshold, 200) 首先运行,并且只要启用了跟踪标志3605,一旦超过阈值,它将输出信息。SQL Server不会收集此信息,以防万一您以后可以运行它。
马丁·史密斯

2
谢谢。只需添加一个具有有用功能的链接即可转换xevents中的resource_0,1,2值。sqlnotes.info/2011/10/24/…–
jesijesi

5

如果您对锁定感兴趣,可以使用几种扩展事件:

lock_acquired
lock_released
lock_escalation

前两个事件有一个duration以微秒为单位的列,您可以根据该列过滤阈值。他们还有一个resource_description动作,可以为您提供有关所涉及资源的详细信息。

lock_escalation事件还具有statement可以添加以收集触发锁升级的T-SQL语句的操作。它也有escalation_cause。这是一个示例会话:

CREATE EVENT SESSION [locking] ON SERVER 
ADD EVENT sqlserver.lock_acquired( SET collect_resource_description = (1) ),
ADD EVENT sqlserver.lock_escalation( SET collect_statement = (1) ),
ADD EVENT sqlserver.lock_released( SET collect_resource_description = (1) )
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

我怀疑您可能无法将阻止的进程报告阈值设置为小于一秒的原因是:在RDBMS中锁定完全是正常的-数据库引擎必须锁定资源以保护资源。尽管尚无关于何时锁定变为阻塞的正式定义,但锁定滴答声在不到一秒的时间内对我来说似乎很正常。


1
一旦其他人被拒绝访问资源,并且由于锁定而不得不等待,锁定就会变成阻塞。
马丁·史密斯

谢谢,我正打算在工期字段中使用lock_acquired。
jesijesi

祝好运。与使用SQL Server 2014一样,您可以将内存OLTP表与本地编译的存储过程一起使用,从而提供高性能的无闩锁选项。您还可以查看快照隔离。
wBob
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.