如何跟踪发生不到一秒的阻塞 - SQL Server

jes*_*esi 14 performance sql-server sql-server-2014 query-performance performance-tuning

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

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

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

有没有其他方法可以跟踪这个。谢谢

Mar*_*ith 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;  
Run Code Online (Sandbox Code Playgroud)

以上收集了在阈值时间内等待锁的语句,但没有给出特定的锁资源。

我从来没有使用过这个事件,也不知道这个会话会在你的生产服务器上造成多少开销。

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

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

dbcc lock(StallReportThreshold, 200) -- 200 is threshold in ms
Run Code Online (Sandbox Code Playgroud)

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

进程 53 为 RID 上的 S 锁等待了 6844 毫秒:2:1:120:2 结果:OKWAIT

我只是顺便提一下,因为无论如何扩展事件显然更可取,因为它有文档记录并且功能更强大。

  • 谢谢。只需添加一个链接,该链接具有转换 xevents 中的 resource_0,1,2 值的有用功能。http://www.sqlnotes.info/2011/10/24/locking-and-blocking-5-lock-resources-in-extended-events/ (2认同)

wBo*_*Bob 5

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

lock_acquired
lock_released
lock_escalation
Run Code Online (Sandbox Code Playgroud)

前两个事件有一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
Run Code Online (Sandbox Code Playgroud)

我怀疑您不能将阻塞进程报告阈值设置为小于一秒可能是有原因的:锁定在 RDBMS 中是完全正常的 - 数据库引擎必须锁定资源以保护它们。虽然没有关于何时锁定变成阻塞的官方定义,但锁定在亚秒内滴答作响,对我来说似乎很正常。