Extended Events to detect deadlock and long running query

Dear all,

I know since SQL 2012, we can use Extended Events to detect deadlock and long running query and see the log size of that long running query,

any step by step guide on how to do it ?
LVL 1
marrowyungSenior Technical architecture (Data)Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Vitor MontalvãoMSSQL Senior EngineerCommented:
Follow are the commands for create the extended events:
CREATE EVENT SESSION CaptureDeadlocks
ON SERVER
ADD EVENT sqlserver.lock_deadlock
(ACTION
(sqlserver.sql_text
            ,sqlserver.database_id
            ,sqlserver.client_app_name))

CREATE EVENT SESSION LongRunningQuery
ON SERVER
ADD EVENT sqlserver.sql_statement_completed
(
ACTION (sqlserver.sql_text, sqlserver.tsql_stack)
WHERE sqlserver.sql_statement_completed.duration > 10000)

Open in new window

NOTE: Duration are in milliseconds, so the example is to capture all queries running for more than 10 seconds.
0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
Deadlocks are already captured in whats called system_health extended events.
You can retrieve from there.
will supply code shortly

Added link to code:
http://blogs.technet.com/b/sqlpfeil/archive/2013/05/27/did-you-know-dead-locks-can-be-track-from-the-system-health-in-sql-2012.aspx

Regards Marten
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

marrowyungSenior Technical architecture (Data)Author Commented:
martenrune,

but one thing, is the XEvent only support since 2012 but not SQL server 2008 ? but by that link I see that:

"If you were lucky enough to work with SQL 2008/2008R2 you could have tried using XEvents (which were introduced in SQL 2008)."

so is the steps on setting up on SQL server 2008 is much the same as creating the same thing on SQL server 2012/14?

Vitor Montalvão,

the XEvent will KEEP RUNNING by itself automatically? where is the result it stores ? I don't see any manual made table at all.

so the script you gave me only do this "capture all queries running for more than 10 seconds" but not deadlock ?

anyway to monitoring deadlock so that I can come back to office tomorrow night and check any deadlock last night after I back home ?
0
marrowyungSenior Technical architecture (Data)Author Commented:
By the way, can XEvent detect which table and database has the most concurrent user to access it and order that by number of user accessed it?
0
Vitor MontalvãoMSSQL Senior EngineerCommented:
so the script you gave me only do this "capture all queries running for more than 10 seconds" but not deadlock ?
No. There are two CREATE EVENT SESSION. First one for Deadlock and second one for Long Running Queries:
ExtendedEvents.PNG
the XEvent will KEEP RUNNING by itself automatically?
No. The code I gave only create the sessions. You can start them by running the following command:
ALTER EVENT SESSION [CaptureDeadlocks] ON SERVER 
STATE=START

ALTER EVENT SESSION [LongRunningQuery] ON SERVER 
STATE=START

Open in new window

And for stop:
ALTER EVENT SESSION [CaptureDeadlocks] ON SERVER 
STATE=STOP

ALTER EVENT SESSION [LongRunningQuery] ON SERVER 
STATE=STOP

Open in new window


where is the result it stores ?
You can store the results in a file:
CREATE EVENT SESSION CaptureDeadlocks
ON SERVER
ADD EVENT sqlserver.lock_deadlock
(ACTION
(sqlserver.sql_text
            ,sqlserver.database_id
            ,sqlserver.client_app_name))
ADD TARGET package0.event_file(SET filename=N'C:\traces\Deadlocks.xel')

Open in new window


Anyway you can query them when they are running by using the following DMVs:
SELECT * FROM sys.dm_xe_sessions;
SELECT * FROM sys.dm_xe_session_events;

Open in new window

Or only for the ones you created:
SELECT s.name, s.create_time, e.*
FROM sys.dm_xe_sessions s
	INNER JOIN sys.dm_xe_session_events e ON s.address=e.event_session_address
WHERE s.name IN ('CaptureDeadlocks','LongRunningQuery')

Open in new window

0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
Hi
Quote:"If you were lucky enough to work with SQL 2008/2008R2 you could have tried using XEvents (which were introduced in SQL 2008)."
and
"so is the steps on setting up on SQL server 2008 is much the same as creating the same thing on SQL server 2012/14?"

It's the system_health extended events. It's similar to default trace in sql 2005. I e it's already setup if you install normally. And it captures deadlocks, so the issue is to find those.

I use two Querys to find what deadlock i'm persuing. the first gives me info about dates and times, the second gives me the XML for the deadlock. If the first shows a deadlock that you want to investigate on row 78, then run the XML script and click on the link on row 78. thats it!

Script 1
************************************************************************************
IF OBJECT_ID('tempdb..#SystemHealthSessionData') IS NOT NULL  
  DROP TABLE #SystemHealthSessionData
GO

-- Fetch the Health Session data into a temporary table
SELECT CAST(xet.target_data AS XML) AS XMLDATA
INTO #SystemHealthSessionData
FROM sys.dm_xe_session_targets xet
JOIN sys.dm_xe_sessions xe
ON (xe.address = xet.event_session_address)
WHERE xe.name = 'system_health'
-- Gets the Deadlock Event Time and Victim Process
SELECT C.query('.').value('(/event/@timestamp)[1]', 'datetime') as EventTime,
 DATEADD(hour,2,C.query('.').value('(/event/@timestamp)[1]', 'datetime')) as SQLServerEventTime,
CAST(C.query('.').value('(/event/data/value)[1]', 'varchar(MAX)') AS XML).value('(/deadlock/victim-list/victimProcess/@id)[1]','varchar(100)') VictimProcess

FROM #SystemHealthSessionData a
CROSS APPLY a.XMLDATA.nodes('/RingBufferTarget/event') as T(C)
WHERE C.query('.').value('(/event/@name)[1]', 'varchar(255)') = 'xml_deadlock_report'
-- Drop the temporary table

-- Drop the temporary table
IF OBJECT_ID('tempdb..#SystemHealthSessionData') IS NOT NULL  
  DROP TABLE #SystemHealthSessionData
GO
************************************************************************************

Script 2
************************************************************************************
declare @xml xml

select @xml = target_data
from sys.dm_xe_session_targets
join sys.dm_xe_sessions on event_session_address = address
where name = 'system_health'

if (substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 1, 5) = '10.00' and cast(substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 7, 4) as int) < 2757)
      or
      (substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 1, 5) = '10.50' and cast(substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 7, 4) as int) < 1702)
begin
      select cast (
            replace (
                  replace (
                        replace (
                              replace (
                                    replace (
                                          replace(replace(replace(xev.xv.value ('(data/value)[1]', 'nvarchar(max)'), ' ','!£$%&'),'%&!£$',''),'!£$%&',' '),
                                          '<victim-list', '<deadlock><victim-list'),
                                    '<victim-list/>', '<victim-list>'),
                              '<process-list>', '</victim-list><process-list>'),
                        char(10), ''),
                  '"> <victimProcess', '" /> <victimProcess')
            as xml)
      from
      (select @xml as tg) AS Data
      cross apply tg.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') as xev (xv)
end
else
begin
      select cast(xev.xv.value ('(data/value)[1]', 'nvarchar(max)') as xml)
      from
      (select @xml as tg) AS Data
      cross apply tg.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') as xev (xv)
end
************************************************************************************

Regards Marten
0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
I found this article, and code that might be better!
http://shamas-saeed.blogspot.se/2014/05/capture-deadlock-information-and.html

****************************************************************************
SELECT
     xed.value('@timestamp', 'datetime2(3)') as CreationDate,
     xed.query('.') AS XEvent
FROM
(
     SELECT CAST([target_data] AS XML) AS TargetData
     FROM sys.dm_xe_session_targets AS st
     INNER JOIN sys.dm_xe_sessions AS s
            ON s.address = st.event_session_address
     WHERE s.name = N'system_health'
                 AND st.target_name = N'ring_buffer'
) AS Data
CROSS APPLY TargetData.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData (xed)
ORDER BY CreationDate DESC
****************************************************************************

Regards Marten
0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
Last posting, XML Deadlock has a bug where one field is not terminated. This shows dates AND a good XML!

************************************************************************
declare @xml xml

select @xml = target_data
from sys.dm_xe_session_targets
join sys.dm_xe_sessions on event_session_address = address
where name = 'system_health'

if (substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 1, 5) = '10.00' and cast(substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 7, 4) as int) < 2757)
      or
      (substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 1, 5) = '10.50' and cast(substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 7, 4) as int) < 1702)
begin
      select cast (
            replace (
                  replace (
                        replace (
                              replace (
                                    replace (
                                          replace(replace(replace(xev.xv.value ('(data/value)[1]', 'nvarchar(max)'), ' ','!£$%&'),'%&!£$',''),'!£$%&',' '),
                                          '<victim-list', '<deadlock><victim-list'),
                                    '<victim-list/>', '<victim-list>'),
                              '<process-list>', '</victim-list><process-list>'),
                        char(10), ''),
                  '"> <victimProcess', '" /> <victimProcess')
            as xml)
      from
      (select @xml as tg) AS Data
      cross apply tg.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') as xev (xv)
end
else
begin
      select
      xev.xv.value('@timestamp', 'datetime2(3)') as CreationDate,
      cast(xev.xv.value ('(data/value)[1]', 'nvarchar(max)') as xml) AS XEvent
      from
      (select @xml as tg) AS Data
      cross apply tg.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') as xev (xv)
end
************************************************************************

Regards Marten
0
marrowyungSenior Technical architecture (Data)Author Commented:
if we use the Xevent to log down slow query, can it log down where the query from and which process execute it and execution plan include so that we can follow up later?
0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
Xevent will NOT log the Queryplan, it's requested and perhaps it will come in SQL2016 or later.
You will get user, but not Calling spid

If you use Xevent to log down slow Query, it will probably not give you the plan, since the extended events fires before the optimizer will auto parameterize the inline literals with variables to compile the query plan for execution. Giving you the wrong plan_handle, but Xevent was correct at the time of the event fireing. Lookat:
https://www.sqlskills.com/blogs/jonathan/what-plan_handle-is-extended-events-sqlserver-plan_handle-action-returning/

You can capture Calling spid, but then you have to compare two extended event traces with each other on som field. I haven't done that yet.

Regards Marten
0
marrowyungSenior Technical architecture (Data)Author Commented:
Victor:

after using your script to create xEVent for both Deadlock and slow query, I see both session but when I open the property sheet of the LongRunningQuery I saw this, any problem ?

creating xEvtn
"You can store the results in a file:"

so I can modify in this way:

CREATE EVENT SESSION CaptureDeadlocks
ON SERVER
ADD EVENT sqlserver.lock_deadlock
(ACTION
(sqlserver.sql_text
            ,sqlserver.database_id
            ,sqlserver.client_app_name))
ADD TARGET package0.event_file(SET filename=N'C:\traces\Deadlocks.xel')

CREATE EVENT SESSION LongRunningQuery
ON SERVER
ADD EVENT sqlserver.sql_statement_completed
(
ACTION (sqlserver.sql_text, sqlserver.tsql_stack)
WHERE sqlserver.sql_statement_completed.duration > 10000)
ADD TARGET package0.event_file(SET filename=N'C:\traces\longrunningquery.xel')

Open in new window


?

what is 'package0.event_file" is about ? for the second add target, should I change it to package1.event_file instead of 0 ?

for the file with extension .xel, both of the query below will check these files ?

SELECT * FROM sys.dm_xe_sessions;

SELECT * FROM sys.dm_xe_session_events;


SELECT s.name, s.create_time, e.*
FROM sys.dm_xe_sessions s
	INNER JOIN sys.dm_xe_session_events e ON s.address=e.event_session_address
WHERE s.name IN ('CaptureDeadlocks','LongRunningQuery')

Open in new window


by this:
SELECT s.name, s.create_time, e.*
FROM sys.dm_xe_sessions s
	INNER JOIN sys.dm_xe_session_events e ON s.address=e.event_session_address
WHERE s.name IN ('CaptureDeadlocks','LongRunningQuery')

Open in new window


what is the use of event_session_address? this is the spid of that query ? and what is the use of event_package_guid and event_predicate ?

martenrune,

"Xevent will NOT log the Queryplan, it's requested and perhaps it will come in SQL2016 or later.
 You will get user, but not Calling spid
"

that one is the SQL login user, right? but it will log the full/complete query, right? (I can replay it and check out the estimated execution plan

one important thing is if we don't query by the query you show me, we are not going to know there are sth happened right? so my question is, any email alert can be setup so that I can know it when outlook prompt emails comes ?

"I use two Querys to find what deadlock i'm persuing. the first gives me info about dates and times, the second gives me the XML for the deadlock. If the first shows a deadlock that you want to investigate on row 78, then run the XML script and click on the link on row 78. thats it!"
"I found this article, and code that might be better!"

so the most updated code you are using is the second one ?

so I find if there are deadlock first( last night for example)

SELECT
      xed.value('@timestamp', 'datetime2(3)') as CreationDate,
      xed.query('.') AS XEvent
 FROM
 (
      SELECT CAST([target_data] AS XML) AS TargetData
      FROM sys.dm_xe_session_targets AS st
      INNER JOIN sys.dm_xe_sessions AS s
             ON s.address = st.event_session_address
      WHERE s.name = N'system_health'
                  AND st.target_name = N'ring_buffer'
 ) AS Data
 CROSS APPLY TargetData.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData (xed)
 ORDER BY CreationDate DESC

Open in new window


then if there are, then I run this to check in detail ?

declare @xml xml

 select @xml = target_data
 from sys.dm_xe_session_targets
 join sys.dm_xe_sessions on event_session_address = address
 where name = 'system_health'

 if (substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 1, 5) = '10.00' and cast(substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 7, 4) as int) < 2757)
       or
       (substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 1, 5) = '10.50' and cast(substring(cast (serverproperty('ProductVersion') as nvarchar(20)), 7, 4) as int) < 1702)
 begin
       select cast (
             replace (
                   replace (
                         replace (
                               replace (
                                     replace (
                                           replace(replace(replace(xev.xv.value ('(data/value)[1]', 'nvarchar(max)'), ' ','!£$%&'),'%&!£$',''),'!£$%&',' '),
                                           '<victim-list', '<deadlock><victim-list'),
                                     '<victim-list/>', '<victim-list>'),
                               '<process-list>', '</victim-list><process-list>'),
                         char(10), ''),
                   '"> <victimProcess', '" /> <victimProcess')
             as xml)
       from
       (select @xml as tg) AS Data
       cross apply tg.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') as xev (xv)
 end
 else
 begin
       select 
       xev.xv.value('@timestamp', 'datetime2(3)') as CreationDate,
       cast(xev.xv.value ('(data/value)[1]', 'nvarchar(max)') as xml) AS XEvent
       from
       (select @xml as tg) AS Data
       cross apply tg.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') as xev (xv)
 end

Open in new window


?

so if there are entries I will just double clik the XEvent which is the XML format of the queries?

"It's the system_health extended events"

so it is type of XEvent we can setup in SQL server 2008  and so on ? right now my empty SQL server 2014 server show me empty entries by your script, any xEvent I have to enable first on SQL server 2008 ?

as the system_health Xevent is on by defauylt in 2014, seems no need to create the 2 x XEvents by Victor at all in SQL 2014?

but the query to retrieve information by Victor return a lot more information :

SELECT * FROM sys.dm_xe_sessions;

SELECT * FROM sys.dm_xe_session_events;


SELECT s.name, s.create_time, e.*
FROM sys.dm_xe_sessions s
	INNER JOIN sys.dm_xe_session_events e ON s.address=e.event_session_address
WHERE s.name IN ('CaptureDeadlocks','LongRunningQuery')

Open in new window

0
marrowyungSenior Technical architecture (Data)Author Commented:
executes me, any feedback on this ?
0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
OK, here goes, I'm gonna aswer Everything:

Quote: "Victor:... after using your script to create xEVent for both Deadlock and slow query, I see both session but when I open the property sheet of the LongRunningQuery I saw this, any problem ?"

The Extended events are being expanded with every version of SQL Server. So if it gives an error, that predicate or action is not implemented in that version. EEvent (gonna write it like this from now on) was implemented in SQL2008. But a gui first came with sql 2012.

Quote: "'package0.event_file", this is like a default package. Do not alter to package1...

Quote: "that one is the SQL login user, right? but it will log the full/complete query, right? (I can replay it and check out the estimated execution plan"
Yes you can and you can check the estimated plan.

Quote:"Deadlocks...then if there are, then I run this to check in detail ?"
Yes, thats how you find information about them.

Quote:"as the system_health Xevent is on by defauylt in 2014, seems no need to create the 2 x XEvents by Victor at all in SQL 2014? ... but the query to retrieve information by Victor return a lot more information "
Yes this is natural, if you set up Another EEvent session, you can add mor information. But it will put (a small but still) an additional stress on your SQL. If the system_health EEvent doesn't provide what you want, this is the solution. Thats up to you. I thought it might be nice to know that on all your servers you already have the system_health EEVent to Query for information, since it's enabled by default.

What is your real question? Try these out, check out by creating a slow Query or a deadlock and examine if this will give you what your'e after. Do you need more help? Is it unclear whats stated above. If so ask and I will try to explain.

Perhaps you should read up on EEvent. Well help you, but it's imperative that you understand what we aree suggesting. For example, a predicate in EEvent can be used with a filter (i e it will not fire unless the filter evaluates to true, wich means that it can be tailored to only give you information on a specific Query, object, login or whatever is a predicate on that SQL Version) So it will not slow down your SQL Server unless the filter is true. This is not the case on an action. It cannot be filtered. For example, T-SQL code is an action in SQL 2008, but a predicate in SQL2014 (not sure about 2012). So I can in 2014 filter for a specific WHERE T-SQL Like '%sometext%' and this will act as a filter on the predicate. In SQL 2008 I have to gather all T-SQL (actions), and then Query them for WHERE T-SQL Like '%sometext%' . But It will have been a strain on the SQL-Server/Instance gathering all the T-SQL since it was an action, and not a predicate.

Regards Marten
0
Vitor MontalvãoMSSQL Senior EngineerCommented:
Sorry, I usually don't connect to EE during weekend but looks like Marten already did a good job by replying to you.
0
marrowyungSenior Technical architecture (Data)Author Commented:
martenrune,

good and please follow me more on my question. let's check.
0
marrowyungSenior Technical architecture (Data)Author Commented:
sorry since the beginning of this week I am onboard on a new job, please give me sometime here to read your message.
0
Marten RuneSQL Expert/Infrastructure ArchitectCommented:
marrowjung

Any Feedback?!?
If the solutions are unacceptable, then write that this is the case and the reason. Otherwise you won't get any more proposed solutions, since the experts feels that the case is solved.

Regards Marten
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
marrowyungSenior Technical architecture (Data)Author Commented:
sorry will 100% considering this as now I am focusing on index tuning, no time for this but we are using 2008 at office and will focus on this.

will let you know later, please come and help even I am closing ticket now.
0
marrowyungSenior Technical architecture (Data)Author Commented:
will come back later if I encounter problem when trying this.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft SQL Server 2008

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.