Blocked Process Report
Profiler提供一个被阻塞进程报告的事件Errors and Warnings->Blocked Process Report

指示某个任务已被阻塞,导致超过指定的时间。此事件类不包括系统任务和正在等待未发现死锁的资源的任务。若要配置报告的频率,请使用 sp_configure 命令配置阻塞的进程阈值选项。

默认阈值为0,此时出现阻塞不会触发此事件,可以使用下面脚本设置该阈值为5秒

exec sp_configure 'blocked process threshold',5;
reconfigure;
select * from sys.configurations
--where name='blocked process threshold (s)'
order by name

我们运行下面语句,创建一个阻塞的查询

--创建测试数据表
IF (SELECT OBJECT_ID('dbo.t1')
) IS NOT NULL
DROP TABLE dbo.t1
GO
CREATE TABLE dbo.t1
(c1 INT
,c2 INT
,c3 DATETIME)
INSERT INTO dbo.t1
VALUES (11, 12, GETDATE())
INSERT INTO dbo.t1
VALUES (21, 22, GETDATE()) --会话1执行
BEGIN TRAN user1
UPDATE dbo.t1 SET c3=GETDATE()
--ROLLBACK --会话2执行
BEGIN TRAN user2
SELECT c2 FROM dbo.t1 WHERE c1=11
--ROLLBACK

在超过被阻塞进程阈值之后,可以在Profiler中看到Blocked Process Report事件被触发

如果保持代码一直运行,每5秒它将被触发一次,所生成的是一个XML文件

<blocked-process-report>
<blocked-process>
<process id="process14f4c8" taskpriority="0" logused="0" waitresource="RID: 6:1:90:0" waittime="36021" ownerId="85965" transactionname="user2" lasttranstarted="2016-12-11T22:44:17.640" XDES="0xcd51730" lockMode="S" schedulerid="1" kpid="1872" status="suspended" spid="56" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2016-12-11T22:44:17.640" lastbatchcompleted="2016-12-11T22:44:12.160" lastattention="2016-12-11T21:18:25.980" clientapp="Microsoft SQL Server Management Studio - 查询" hostname="VUEST" hostpid="1700" loginname="VUEST\Vuest" isolationlevel="read committed (2)" xactid="85965" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<executionStack>
<frame line="2" stmtstart="38" sqlhandle="0x020000001be0f42a9b3a6fd8eae5b4ae648e87cc70b1f6ba"/>
<frame line="2" stmtstart="38" sqlhandle="0x0200000008b74f04b02b5eed91a834b9706e0fc33245acd6"/>
</executionStack>
<inputbuf>
begin tran user2
select c2 from dbo.t1 where c1=11 </inputbuf>
</process>
</blocked-process>
<blocking-process>
<process status="sleeping" spid="52" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2016-12-11T22:44:09.750" lastbatchcompleted="2016-12-11T22:44:09.790" clientapp="Microsoft SQL Server Management Studio - 查询" hostname="VUEST" hostpid="1700" loginname="VUEST\Vuest" isolationlevel="read committed (2)" xactid="85956" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack/>
<inputbuf>
begin tran user1
update dbo.t1 set c3=GETDATE() </inputbuf>
</process>
</blocking-process>
</blocked-process-report>

此时用语句获取阻塞信息

        --得到阻塞对应关系
SELECT distinct
wt.session_id AS BlockedSessionId,
DB_NAME(tl.resource_database_id) AS DatabaseName,
wt.wait_type AS WaitType,
tl.request_mode+':'+tl.resource_type+':'+tl.resource_description AS WaitResource,
se1.last_request_start_time AS BlockedTime,ec1.last_read,
wt.wait_duration_ms AS WaitDuration_ms,
ec1.client_net_address AS BlockedClientAddress,
--h1.text AS BlockedStmt,
SUBSTRING(
h1.text,
(er1.statement_start_offset / 2) + 1,
(
(
CASE
WHEN er1.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), h1.text))
* 2
ELSE er1.statement_end_offset
END - er1.statement_start_offset
) / 2
) + 1
) AS BlockedStmt,
wt.blocking_session_id AS BlockingSessionId,
se2.transaction_isolation_level AS BlockingIsolationLevel,
wt.resource_description AS BlockingHoldResource,
--h2.text AS BlockingStmt,
SUBSTRING(
h2.text,
(ISNULL(er2.statement_start_offset, 0) / 2) + 1,
(
(
CASE
WHEN ISNULL(er2.statement_end_offset, 0) <= 0 THEN
LEN(CONVERT(NVARCHAR(MAX), h2.text))
* 2
ELSE er2.statement_end_offset
END - ISNULL(er2.statement_start_offset, 0)
) / 2
) + 1
) AS BlockingStmt,
ec2.client_net_address AS BlockingClientAddress,
se2.program_name AS BlockingProgramName,
se2.login_name AS BlockingLoginame,
GETDATE() AS InsertTime
FROM sys.dm_tran_locks AS tl WITH(NOLOCK) --会过滤并行问题CXPACKET
INNER JOIN sys.dm_os_waiting_tasks AS wt WITH(NOLOCK)
ON wt.resource_address = tl.lock_owner_address
INNER JOIN sys.dm_exec_connections ec1 WITH(NOLOCK)
ON ec1.session_id = wt.session_id
INNER JOIN sys.dm_exec_connections ec2 WITH(NOLOCK)
ON ec2.session_id = wt.blocking_session_id
INNER JOIN sys.dm_exec_sessions AS se1 WITH(NOLOCK)
ON se1.session_id = ec1.session_id
INNER JOIN sys.dm_exec_sessions AS se2 WITH(NOLOCK)
ON se2.session_id = ec2.session_id
INNER JOIN sys.dm_exec_requests er1 WITH(NOLOCK)
ON er1.session_id = ec1.session_id
LEFT JOIN sys.dm_exec_requests er2 WITH(NOLOCK)
ON er2.session_id = ec2.session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2


自动化侦测和收集阻塞信息
《SQLServer2008查询性能优化》第355页有说使用[SQL Server警报+作业]来自动侦测和收集阻塞信息。下面参考原文进行测试


[常规]页面计数器Average Wait Time (ms)(我使用计数器Lock Wait Time (ms)一直收不到邮件)对应的是累计值,并且只有当阻塞解除后才会进行累加。例如我重启数据库服务,然后执行前面的创建阻塞语句,只要会话1不回滚/提交,阻塞将一直持续,计数器Average Wait Time (ms)的值不会变动。一旦会话1回滚/提交,计数器Average Wait Time (ms)的值将更新(原值+阻塞时长)。当计数器Average Wait Time (ms)的值满足设定的警报条件时,它将触发警报并响应动作(此例中:执行作业+通知操作员)。之后哪怕没有阻塞,警报还将一直被触发(计数器Average Wait Time (ms)的值一直满足触发警报条件)。警报相关操作可参考:SQL Server代理警报
警报的[响应]页面勾选的执行作业Blocking Analysis,作业执行的语句实际是[将Profiler中定义Blocked Process Report事件导出生成跟踪定义的脚本]

-- Create a Queue
declare @rc int
declare @TraceID int
declare @maxfilesize BIGINT
declare @DateTime datetime
declare @TraceFile nvarchar(256) set @DateTime = DATEADD(MI,5,GETDATE())
set @maxfilesize = 5
select @TraceFile='F:\TroubleShooting\'+REPLACE(@@SERVERNAME,'\','_')+'_Blocked' exec @rc = sp_trace_create @TraceID output, 2, @TraceFile, @maxfilesize, @Datetime
if (@rc != 0) goto error -- Client side File and Table cannot be scripted -- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 137, 1, @on
exec sp_trace_setevent @TraceID, 137, 3, @on
exec sp_trace_setevent @TraceID, 137, 4, @on
exec sp_trace_setevent @TraceID, 137, 12, @on
exec sp_trace_setevent @TraceID, 137, 13, @on
exec sp_trace_setevent @TraceID, 137, 14, @on
exec sp_trace_setevent @TraceID, 137, 15, @on
exec sp_trace_setevent @TraceID, 137, 24, @on
exec sp_trace_setevent @TraceID, 137, 32, @on
exec sp_trace_setevent @TraceID, 137, 41, @on
exec sp_trace_setevent @TraceID, 137, 51, @on -- Set the Filters
declare @intfilter int
declare @bigintfilter bigint -- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1 -- display trace id for future references
select TraceID=@TraceID
goto finish error:
select ErrorCode=@rc finish:
go

将上面脚本保存到.sql文件,作业步骤类型使用cmdExec,命令中键入:sqlcmd -E -S127.0.0.1,7777 -iF:\TroubleShooting\TraceBlocked.sql
语句查询计数器的取值

select * from sys.dm_os_performance_counters
WHERE [object_name]='MSSQL$SQL08R2:Locks'
AND instance_name='_Total'
ORDER BY counter_name


收到的邮件

个人对这种自动化侦测和收集不太满意,原因就是警报触发条件所使用的计数器是累计值。更多的时候我们希望遇到阻塞,并且阻塞时长持续>某个值的时候能有提醒。因此倾向于定期从sys.dm_os_waiting_tasks中获取阻塞信息。

如何使用Profiler跟踪阻塞信息的更多相关文章

  1. NET Memory Profiler 跟踪.net 应用内存

    NET Memory Profiler 跟踪.net 应用内存 用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇 作者:肖波      .net 框架号称永远 ...

  2. 十、K3 WISE 开发插件《SQL Profiler跟踪单据操作时产生的SQL语句》

    =================================== 目录: 1.查询帐套的数据库DBID 2.配置需要跟踪数据库的DBID 3.配置跟踪参数 4.跟踪进行 5.分析跟踪语句 === ...

  3. PHP打印跟踪调试信息

    对于大部分编译型语言来说,比如 C . Java . C# ,我们都能很方便地进行断点调试,但是 PHP 则必须安装 XDebug 并且在编辑器中进行复杂的配置才能实现断点调试的能力.不过,如果只是简 ...

  4. Sql Server Profiler跟踪死锁

    Sql Server Profiler一个很重要的应用场景就是监视分析死锁. 下面通过一个例子来学习Profiler是如何监视死锁的. 1. 创建测试数据模拟死锁, 创建表Table_A和Table_ ...

  5. 统计分析SQL Server Profiler 跟踪的SQL

    --跟踪文件读入到表中分析 SELECT * INTO ZGSJY FROM fn_trace_gettable('E:\wxxcdbprofiler.trc', default); --某时间内,最 ...

  6. 【SQL跟踪工具】SQL Profiler 跟踪器

    什么是SQL Profiler SQL Server Profiler 是一个功能丰富的界面,用于创建和管理跟踪并分析和重播跟踪结果. 事件保存在一个跟踪文件中,稍后试图诊断问题时,可以对该文件进行分 ...

  7. 用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇(转)

    .net 框架号称永远不会发生内存泄漏,原因是其引入了内存回收的机制.但实际应用中,往往我们分配了对象但没有释放指向该对象的引用,导致对象永远无法释放.最 常见的情况就是给对象添加了事件处理函数,但当 ...

  8. SQLSERVER——查看阻塞信息(sp_who_lock优化无误版)

    经常会需要分析SQLSERVER的阻塞情况,尤其是某些SQL操作异常缓慢从而怀疑是有人在搞事情的情况下.网上有许多一模一样的帖子,是关于sp_who_lock这个存储过程的,然而,网上流传的这个是略有 ...

  9. profiler跟踪事件存为表之后性能分析工具

    使用profiler建立跟踪,将跟踪结果存到表中,使用下面存储过程执行 exec temp_profiler 'tra_tablename'对表数据进行处理归类,然后进行性能分析 1.先建存储过程 2 ...

随机推荐

  1. C#自定义工业控件开发

    由于工作需要,调研过一段时间的工业控制方面的“组态软件”(SCADA)的开发,组态软件常用于自动化工业控制领域,其中包括实时数据采集.数据储存.设备控制和数据展现等功能.其中工控组件的界面展现的实现类 ...

  2. nuget packages batch install

    d:\nuget\nuget.exe install EnterpriseLibrary.Common -NoCache -Verbosity detailed -OutputDirectory D: ...

  3. 用Less CSS定义常用的CSS3效果函数

    定义圆角及调用 /* 定义圆角 @radius 圆角大小 */ .round(@radius:5px){ border-radius:@radius; -webkit-border-radius: @ ...

  4. Android自动化测试 - Robotium之re-sign.jar重签名后安装失败提示Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]解决方案

    问题:在用re-sign.jar重签名apk文件后,显示重签名成功,但在实际安装过程中确提示:Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] 原因:网上查 ...

  5. CentOS 6.5 下安装 Redis 2.8.7

    wget http://download.redis.io/redis-stable.tar.gz tar xvzf redis-stable.tar.gz cd redis-stable make ...

  6. java基础-泛型1

    浏览以下内容前,请点击并阅读 声明 泛型的使用能使类型名称作为类或者接口定义中的参数,就像一般的参数一样,使得定义的类型通用性更强. 泛型的优势: 编译具有严格的类型检查 java编译器对于泛型代码的 ...

  7. maven 项目打包 及window下部署到tomcat

    1.maven项目打包 2.将war文件拷贝到tomcat目录webapps下(不要再建目录)3.将必要的jar文件拷贝到tomcat目录libx下 war包 或jar 包 会生成到项目所在路径 的t ...

  8. crawler4j 学习

    crawler4j 学习(一) crawler4j是一个轻量级多线程网络爬虫,开发者可以调用相应的接口在短时间内创建一个多线程网络爬虫. 前期准备 使用maven 为了使用最近版本的crawler4j ...

  9. ZeroMQ接口函数之 :zmq_socket – 创建ZMQ套接字

    ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html ZeroMQ 官方地址:http://api.zeromq.org/4 ...

  10. 使用express-generator初始化你的项目目录

    express 4.x以后将express命令独立到 express-generator包中,所以想使用express初始化项目目录,可以npm install express-genrator   ...