利用扩展事件和警报实时监控死锁-命令方式

--本篇文章有些错误,待考究,仅供大家参考

一:实验背景

日常工作中,经常会出现一些死锁现象发生,影响系统性能。

因此,我们需要一种方法实时得监控死锁,一旦有死锁,发邮件通知我们,然后由相关人去解决。

扩展事件是一种轻量级的调优工具,占用资源少,高配置性,高扩展性。

所以我们选择用扩展事件监控死锁,然后通过警报,实时得通知我们。

备注:本实验是以自己本地数据库实例做的。

二:试验步骤

1:建事件会话

CREATE EVENTSESSIONMONITORING_DEADLOCK ONSERVER

ADD EVENTsqlserver.xml_deadlock_report

    (

ACTION(sqlos.worker_address,sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.client_pid,sqlserver.database_id,sqlserver.database_name,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.sql_text,sqlserver.username)

    )

 

ADD TARGETpackage0.ring_buffer 

WITH (MAX_DISPATCH_LATENCY= 30SECONDS);

 

--启动该事件会话

ALTER EVENTSESSIONMONITORING_DEADLOCKONSERVERSTATE=START;

GO 

--设置’在服务器启动时启动事件会话‘

(如果服务器重启的话,事件会话默认不启动,这样就查看不了会话目标信息了,因此要进行该设置)。

展开’对象资源管理器‘->管理->会话->右击该事件会话,点击’属性‘,如图:

利用扩展事件和警报实时监控死锁-命令方式_第1张图片

勾选’在服务器启动时启动事件会话‘,如图:

利用扩展事件和警报实时监控死锁-命令方式_第2张图片

--备注:如果服务器重启过的话,之前发生过的死锁信息就看不到了。

--删会话

--DROP EVENT SESSION MONITORING_DEADLOCK ON SERVER

2:建警报

在‘对象资源管理器’中,展开‘SQL SERVER代理’,右击‘警报’->‘新建警报’,如图:

利用扩展事件和警报实时监控死锁-命令方式_第3张图片

2.1:设置‘常规’选项卡

利用扩展事件和警报实时监控死锁-命令方式_第4张图片

--当死锁数量大于0(即出现死锁)时,发出警报。

2.2:设置‘响应’选项卡

选择‘操作员’(若没有现成的‘操作员’,则新建一个,这里之前已经建过一个操作员v-baidd),

利用扩展事件和警报实时监控死锁-命令方式_第5张图片

2.3:设置‘选项’页

在‘要发送的其他通知信息’处自定义信息,如:

利用扩展事件和警报实时监控死锁-命令方式_第6张图片

3:设置SQL SERVER代理

若之前已经设置过警报管理的‘数据库配置文件’,则忽略此步骤。

若第一次建警报的话,需要设置SQL SERVER代理。

右击‘SQL SERVER代理’-‘属性’,

利用扩展事件和警报实时监控死锁-命令方式_第7张图片

在‘警报’选项卡处,勾选‘启用邮件配置文件’,选择要使用的‘邮件配置文件’(这里选择了Profile1)

利用扩展事件和警报实时监控死锁-命令方式_第8张图片

重启SQL SERVER代理服务

4:模拟死锁

--在其中一个窗口输入并执行:

BEGIN TRAN--ROLLBACK

USE TEST;

UPDATE EMP2

SET ename='JIAOJIAO'

WHERE empno=2

WAITFOR DELAY'0:0:25';

UPDATE EMP2

SET ename='SONGSONG'

WHERE empno=4

--SELECT @@SPID  57

--在另一个窗口输入并执行:

BEGIN TRAN--ROLLBACK

USE TEST;

UPDATE EMP2

SET ename='SONGSONG'

WHERE empno=4

WAITFOR DELAY'0:0:25';

 

UPDATE EMP2

SET ename='JIAOJIAO'

WHERE empno=2

--SELECT @@SPID  60

 

就会报这样的错误:

(1 行受影响)

消息 1205,级别 13,状态 51,第 8 行

事务(进程 ID 60)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。

5:收到警报发送的邮件

如图:

利用扩展事件和警报实时监控死锁-命令方式_第9张图片

6:查询事件会话目标信息

6.1查看XML格式信息

SELECT CAST(target_dataASXML)

FROM SYS.DM_XE_SESSIONSA

    INNERJOIN SYS.dm_xe_session_targetsSONA.address=S.event_session_address

WHERE A.name='MONITORING_DEADLOCK'

点击该查询结果,能看到数据库,事务,进程,会话, SQL语句等信息。

XML文档内容如下:

<RingBufferTargettruncated="0"processingTime="0"totalEventsProcessed="2"eventCount="2"droppedCount="0"memoryUsed="16226">

  <eventname="xml_deadlock_report"package="sqlserver"timestamp="2014-05-24T04:09:47.636Z">

    <dataname="xml_report">

      <typename="xml"package="package0" />

      <value>

        <deadlock>

          <victim-list>

            <victimProcessid="process363404188" />

          </victim-list>

          <process-list>

            <processid="process363404188"taskpriority="0"logused="144"waitresource="KEY: 7:72057594050510848 (9d6bf8154a2a)"waittime="4064"ownerId="1841133"transactionname="user_transaction"lasttranstarted="2014-05-24T12:09:18.567"XDES="0x36a4dcd28"lockMode="X"schedulerid="4"kpid="10220"status="suspended"spid="60"sbid="0"ecid="0"priority="0"trancount="2"lastbatchstarted="2014-05-24T12:09:18.567"lastbatchcompleted="2014-05-24T12:09:13.383"lastattention="1900-01-01T00:00:00.383"clientapp="Microsoft SQL ServerManagement Studio - 查询"hostname="ZB-BAIDD-PC"hostpid="4632"loginname="SINOOCEANLAND\v-baidd"isolationlevel="read committed (2)"xactid="1841133"currentdb="7"lockTimeout="4294967295"clientoption1="671090784"clientoption2="390200">

              <executionStack>

                <frameprocname="adhoc"line="8"stmtstart="58"sqlhandle="0x02000000d9418b10cbc871e6336b29994a63088a4ca33f5e0000000000000000000000000000000000000000">

UPDATE [EMP2] set [ename] = @1 WHERE [empno]=@2    </frame>

                <frameprocname="adhoc"line="8"stmtstart="224"sqlhandle="0x02000000b8a0b81a9a3ca4a2a3b0ea4046ed4858dfe471100000000000000000000000000000000000000000">

UPDATE EMP2

SET ename='JIAOJIAO'

WHERE empno=2

--SELECT @@SPID  60    </frame>

              </executionStack>

              <inputbuf>

BEGIN TRAN --ROLLBACK

USE TEST;

UPDATE EMP2

SET ename='SONGSONG'

WHERE empno=4

WAITFOR DELAY '0:0:25';

 

UPDATE EMP2

SET ename='JIAOJIAO'

WHERE empno=2

--SELECT @@SPID  60

   </inputbuf>

            </process>

            <processid="process37567e558"taskpriority="0"logused="332"waitresource="KEY: 7:72057594050510848 (1a39e6095155)"waittime="5553"ownerId="1841125"transactionname="user_transaction"lasttranstarted="2014-05-24T12:09:17.077"XDES="0x366901048"lockMode="X"schedulerid="4"kpid="11312"status="suspended"spid="57"sbid="0"ecid="0"priority="0"trancount="2"lastbatchstarted="2014-05-24T12:09:17.077"lastbatchcompleted="2014-05-24T12:09:15.673"lastattention="1900-01-01T00:00:00.673"clientapp="Microsoft SQL ServerManagement Studio - 查询"hostname="ZB-BAIDD-PC"hostpid="4632"loginname="SINOOCEANLAND\v-baidd"isolationlevel="read committed (2)"xactid="1841125"currentdb="7"lockTimeout="4294967295"clientoption1="671090784"clientoption2="390200">

              <executionStack>

                <frameprocname="adhoc"line="8"stmtstart="58"sqlhandle="0x02000000d9418b10cbc871e6336b29994a63088a4ca33f5e0000000000000000000000000000000000000000">

UPDATE [EMP2] set [ename] = @1 WHERE [empno]=@2    </frame>

                <frameprocname="adhoc"line="8"stmtstart="254"sqlhandle="0x02000000f5add204ea99c109e6338086d7a147bf252cb5560000000000000000000000000000000000000000">

UPDATE EMP2

SET ename='SONGSONG'

WHERE empno=4

--SELECT @@SPID  57    </frame>

              </executionStack>

              <inputbuf>

--在其中一个窗口输入并执行:

BEGIN TRAN --ROLLBACK

USE TEST;

UPDATE EMP2

SET ename='JIAOJIAO'

WHERE empno=2

WAITFOR DELAY '0:0:25';

UPDATE EMP2

SET ename='SONGSONG'

WHERE empno=4

--SELECT @@SPID  57

   </inputbuf>

            </process>

          </process-list>

          <resource-list>

            <keylockhobtid="72057594050510848"dbid="7"objectname="test.dbo.EMP2"indexname="1"id="lock37ab45580"mode="X"associatedObjectId="72057594050510848">

              <owner-list>

                <ownerid="process37567e558"mode="X" />

              </owner-list>

              <waiter-list>

                <waiterid="process363404188"mode="X"requestType="wait" />

              </waiter-list>

            </keylock>

            <keylockhobtid="72057594050510848"dbid="7"objectname="test.dbo.EMP2"indexname="1"id="lock37ab44780"mode="X"associatedObjectId="72057594050510848">

              <owner-list>

                <ownerid="process363404188"mode="X" />

              </owner-list>

              <waiter-list>

                <waiterid="process37567e558"mode="X"requestType="wait" />

              </waiter-list>

            </keylock>

          </resource-list>

        </deadlock>

      </value>

    </data>

    <actionname="username"package="sqlserver">

      <typename="unicode_string"package="package0" />

      <value>sa</value>

    </action>

    <actionname="session_nt_username"package="sqlserver">

      <typename="unicode_string"package="package0" />

      <value />

    </action>

    <actionname="session_id"package="sqlserver">

      <typename="uint16"package="package0" />

      <value>18</value>

    </action>

    <actionname="query_plan_hash"package="sqlserver">

      <typename="uint64"package="package0" />

      <value>0</value>

    </action>

    <actionname="database_name"package="sqlserver">

      <typename="unicode_string"package="package0" />

      <value>master</value>

    </action>

    <actionname="database_id"package="sqlserver">

      <typename="uint16"package="package0" />

      <value>1</value>

    </action>

    <actionname="client_pid"package="sqlserver">

      <typename="uint32"package="package0" />

      <value>0</value>

    </action>

    <actionname="client_hostname"package="sqlserver">

      <typename="unicode_string"package="package0" />

      <value />

    </action>

    <actionname="client_app_name"package="sqlserver">

      <typename="unicode_string"package="package0" />

      <value />

    </action>

    <actionname="worker_address"package="sqlos">

      <typename="ptr"package="package0" />

      <value>0x0000000365b94160</value>

    </action>

  </event>

</RingBufferTarget>

6.2 提取XML数据到关系数据

6.2.1 建视图

6.2.1.1 造成死锁的视图

USE  DBA;

GO

CREATE VIEW Perfermance.v_find_deadlock_1

(

    时间戳,

    SQL语句,

    主机名称,

    登录名称,

    客户端应用程序,

    进程号,

    当前数据库,

    状态,

    等待时间 ,

    kpid,

    锁模式,

    等待资源 ,

    事务隔离级别

)

AS

--一造成死锁的系列信息

SELECT node.event_data.value('(@timestamp)[1]','Datetime')AS时间戳,--小时,分钟不对,只能大概了解日期跟发生的先后顺序

    node.event_data.value('(data/value/deadlock/process-list/process/inputbuf)[2]','NVARCHAR(MAX)')ASSQL语句,

    node.event_data.value('(data/value/deadlock/process-list/process/@hostname)[2]','nvarchar(100)')AS主机名称,

    node.event_data.value('(data/value/deadlock/process-list/process/@loginname)[2]','nvarchar(100)')AS登录名称,

    node.event_data.value('(data/value/deadlock/process-list/process/@clientapp)[2]','nvarchar(200)')AS客户端应用程序,

    node.event_data.value('(data/value/deadlock/process-list/process/@spid)[2]','nvarchar(100)')AS进程号,

    node.event_data.value('(data/value/deadlock/process-list/process/@currentdb)[2]','nvarchar(200)')AS当前数据库,

    node.event_data.value('(data/value/deadlock/process-list/process/@status)[2]','nvarchar(200)')AS状态,

    node.event_data.value('(data/value/deadlock/process-list/process/@waittime)[2]','nvarchar(200)')AS等待时间,

    node.event_data.value('(data/value/deadlock/process-list/process/@kpid)[2]','nvarchar(200)')ASkpid,

    node.event_data.value('(data/value/deadlock/process-list/process/@lockMode)[2]','nvarchar(200)')AS锁模式,

    node.event_data.value('(data/value/deadlock/process-list/process/@waitresource)[2]','nvarchar(200)')AS等待资源,

    node.event_data.value('(data/value/deadlock/process-list/process/@isolationlevel)[2]','nvarchar(200)')AS事务隔离级别

    --             

FROM

    (SELECTCAST(T.TARGET_DATAASXML)AStarget_data

          FROM SYS.dm_xe_sessionsS

                INNER JOIN SYS.DM_XE_SESSION_TARGETSTONS.address=T.event_session_address

          WHERE S.name='MONITORING_DEADLOCK'

    )AS T

    CROSSAPPLYT.target_data.nodes('//RingBufferTarget/event')ASnode(event_data)

6.2.1.2 被作为牺牲品的视图

USE DBA;

GO

CREATE VIEW Perfermance.v_find_deadlock_2

(

    时间戳,

    SQL语句,

    主机名称,

    登录名称,

    客户端应用程序,

    进程号,

    当前数据库,

    状态,

    等待时间 ,

    kpid,

    锁模式,

    等待资源 ,

    事务隔离级别

)

AS

 

SELECT node.event_data.value('(@timestamp)[1]','Datetime')AS时间戳,--小时,分钟不对,只能大概了解日期跟发生的先后顺序

    node.event_data.value('(data/value/deadlock/process-list/process/inputbuf)[1]','NVARCHAR(MAX)')ASSQL语句,

    node.event_data.value('(data/value/deadlock/process-list/process/@hostname)[1]','nvarchar(100)')AS造成死锁所在主机名称,

    node.event_data.value('(data/value/deadlock/process-list/process/@loginname)[1]','nvarchar(100)')AS登录名称,

    node.event_data.value('(data/value/deadlock/process-list/process/@clientapp)[1]','nvarchar(200)')AS客户端登录程序,

    node.event_data.value('(data/value/deadlock/process-list/process/@spid)[1]','nvarchar(100)')AS进程号,

    node.event_data.value('(data/value/deadlock/process-list/process/@currentdb)[1]','nvarchar(200)')AS当前数据库,

    node.event_data.value('(data/value/deadlock/process-list/process/@status)[1]','nvarchar(200)')AS状态,

    node.event_data.value('(data/value/deadlock/process-list/process/@waittime)[1]','nvarchar(200)')AS等待时间,

    node.event_data.value('(data/value/deadlock/process-list/process/@kpid)[1]','nvarchar(200)')ASkpid,

    node.event_data.value('(data/value/deadlock/process-list/process/@lockMode)[1]','nvarchar(200)')AS锁模式,

    node.event_data.value('(data/value/deadlock/process-list/process/@waitresource)[1]','nvarchar(200)')AS等待资源,

    node.event_data.value('(data/value/deadlock/process-list/process/@isolationlevel)[1]','nvarchar(200)')AS事务隔离级别

    --             

FROM

    (SELECTCAST(T.TARGET_DATAASXML)AStarget_data

          FROM SYS.dm_xe_sessionsS

                INNER JOIN SYS.DM_XE_SESSION_TARGETSTONS.address=T.event_session_address

          WHERE S.name='MONITORING_DEADLOCK'

    )AS T

    CROSSAPPLYT.target_data.nodes('//RingBufferTarget/event')ASnode(event_data)


6.2.2 查询造成死锁信息

USE DBA;

SELECT *

FROM v_find_deadlock_2

 

--有必要的话,可以加WHERE条件过滤信息。

6.2.3查看被作为牺牲品的信息

USE DBA;

SELECT *

FROM v_find_deadlock_1

--有必要的话,可以加WHERE条件过滤信息。

结果如图:


--注意:这个时间戳是由timestamp数据类型转换成日期类型的,日期是正确的,但是时分秒不准确。


你可能感兴趣的:(利用扩展事件和警报实时监控死锁-命令方式)