SQLServer扩展事件(ExtendedEvents)--使用system_health默认跟
SQL Server扩展事件(Extended Events)-- 使用system_health默认跟踪会话监控死锁 自SQL Server 2008以后,提供了扩展事件(Extended Events)来跟踪系统分析定位问题。默认的system_health会话一直在运行,可以帮助你更快的定位问题。 运行如下脚本可以看
SQL Server扩展事件(Extended Events)-- 使用system_health默认跟踪会话监控死锁
自SQL Server 2008以后,提供了扩展事件(Extended Events)来跟踪系统分析定位问题。默认的system_health会话一直在运行,可以帮助你更快的定位问题。
运行如下脚本可以看到system_health扩展事件会话:
SELECT * FROM sys.dm_xe_sessions
即便是你没有启动任何扩展事件会话,这个查询也会返回一行system_health会话。
SQL Server 2012版本之前,并不提供管理扩展事件会话的图形界面,你可以从这里下载SQL Server 2008 Extended Events SSMS Addin插件:http://extendedeventmanager.codeplex.com/
安装好后,可以按如图方式找到扩展事件管理界面:
650) this.width=650;" title="clip_image001" style="max-width:90%" alt="clip_image001" border="0" style="max-width:90%" />
650) this.width=650;" title="clip_image002" style="max-width:90%" alt="clip_image002" border="0" style="max-width:90%" />
而在SQL Server 2012版本中,则通过如图方式可以找到该界面:
650) this.width=650;" title="clip_image003" style="max-width:90%" alt="clip_image003" border="0" style="max-width:90%" />
我们右键点击“system_health”,生成脚本,我们可以看到该会话的内容如下(SQL Server 2012版本):
CREATE EVENT SESSION [system_health] ON SERVER ADD EVENT sqlclr.clr_allocation_failure( ACTION(package0.callstack,sqlserver.session_id)), ADD EVENT sqlclr.clr_virtual_alloc_failure( ACTION(package0.callstack,sqlserver.session_id)), ADD EVENT sqlos.memory_broker_ring_buffer_recorded, ADD EVENT sqlos.memory_node_oom_ring_buffer_recorded( ACTION(package0.callstack,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_stack)), ADD EVENT sqlos.scheduler_monitor_deadlock_ring_buffer_recorded, ADD EVENT sqlos.scheduler_monitor_non_yielding_iocp_ring_buffer_recorded, ADD EVENT sqlos.scheduler_monitor_non_yielding_ring_buffer_recorded, ADD EVENT sqlos.scheduler_monitor_non_yielding_rm_ring_buffer_recorded, ADD EVENT sqlos.scheduler_monitor_stalled_dispatcher_ring_buffer_recorded, ADD EVENT sqlos.scheduler_monitor_system_health_ring_buffer_recorded, ADD EVENT sqlos.wait_info( ACTION(package0.callstack,sqlserver.session_id,sqlserver.sql_text) WHERE ([duration]>(15000) AND ([wait_type]>(31) AND ([wait_type]>(47) AND [wait_type]<(54) OR [wait_type]<(38) OR [wait_type]>(63) AND [wait_type]<(70) OR [wait_type]>(96) AND [wait_type]<(100) OR [wait_type]=(107) OR [wait_type]=(113) OR [wait_type]>(174) AND [wait_type]<(179) OR [wait_type]=(186) OR [wait_type]=(207) OR [wait_type]=(269) OR [wait_type]=(283) OR [wait_type]=(284)) OR [duration]>(30000) AND [wait_type]<(22)))), ADD EVENT sqlos.wait_info_external( ACTION(package0.callstack,sqlserver.session_id,sqlserver.sql_text) WHERE ([duration]>(5000) AND ([wait_type]>(365) AND [wait_type]<(372) OR [wait_type]>(372) AND [wait_type]<(377) OR [wait_type]>(377) AND [wait_type]<(383) OR [wait_type]>(420) AND [wait_type]<(424) OR [wait_type]>(426) AND [wait_type]<(432) OR [wait_type]>(432) AND [wait_type]<(435) OR [duration]>(45000) AND ([wait_type]>(382) AND [wait_type]<(386) OR [wait_type]>(423) AND [wait_type]<(427) OR [wait_type]>(434) AND [wait_type]<(437) OR [wait_type]>(442) AND [wait_type]<(451) OR [wait_type]>(451) AND [wait_type]<(473) OR [wait_type]>(484) AND [wait_type]<(499) OR [wait_type]=(365) OR [wait_type]=(372) OR [wait_type]=(377) OR [wait_type]=(387) OR [wait_type]=(432) OR [wait_type]=(502))))), ADD EVENT sqlserver.connectivity_ring_buffer_recorded(SET collect_call_stack=(1)), ADD EVENT sqlserver.error_reported( ACTION(package0.callstack,sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_stack) WHERE ([severity]>=(20) OR ([error_number]=(17803) OR [error_number]=(701) OR [error_number]=(802) OR [error_number]=(8645) OR [error_number]=(8651) OR [error_number]=(8657) OR [error_number]=(8902)))), ADD EVENT sqlserver.security_error_ring_buffer_recorded(SET collect_call_stack=(1)), ADD EVENT sqlserver.sp_server_diagnostics_component_result(SET collect_data=(1) WHERE ([sqlserver].[is_system]=(1) AND [component]<>(4))), ADD EVENT sqlserver.xml_deadlock_report ADD TARGET package0.event_file(SET filename=N'system_health.xel',max_file_size=(5),max_rollover_files=(4)), ADD TARGET package0.ring_buffer(SET max_events_limit=(5000),max_memory=(4096)) WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=120 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=ON) GO
你也可以在SQL Server的安装目录:C:\Program Files\Microsoft SQL Server\MSSQL11.
下找到脚本u_tables.sql文件。
从定义可以看到,会话的输出包含callstack、sessionID、TSQL和TSQL Call Stack
且当安全等级大于20或者错误号为17803等。它们与内存压力相关、Non-yielding scheduler问题、死锁和一些类型的等待。
会话输出被捕获到遵从FIFO规则的ring_buffer中,ring_buffer是一个内存使用者,它以二进制格式存储捕获数据。当事件会话启用的时候,数据即可被捕获。当停止会话的时候,分配给ring_buffer的内存被释放,且数据消失。注意:对于SQL Server 2012之前,system_health的目标只有ring_buffer,从SQL Server 2012开始,增加了event_file的输出。
你可以通过关联sys.dm_xe_session_targets和sys.dm_xe_sessions视图来查看ring_buffer或event_file的内容,并转换二进制数据为XML格式。
SELECT name, target_name, CAST(target_data AS XML) target_data FROM sys.dm_xe_sessions s INNER JOIN sys.dm_xe_session_targets t ON s.address = t.event_session_address WHERE s.name = 'system_health' GO
注意:event_file的输出是文件的存储路径,而ring_buffer的输出是捕获到的数据。
在ring_buffer中,每一个事件元素都有一个数据子集和一个动作子集。这些动作是在会话的定义中。数据元素包含了每个事件的数据类型列的所有值。这些列可通过sys.dm_xe_object_columns视图输出。让我们解析XML格式以表格格式查看内容。因为每个事件返回数据列的不同集合。下面给一个error_reported事件的例子。
DECLARE @x XML = (SELECT CAST(target_data AS XML) FROM sys.dm_xe_sessions s INNER JOIN sys.dm_xe_session_targets t ON s.address = t.event_session_address WHERE s.name = 'system_health' and t.target_name = 'ring_buffer') SELECT t.e.value('@name', 'varchar(50)') AS EventName ,t.e.value('@timestamp', 'datetime') AS DateAndTime ,t.e.value('(data[@name="error"]/value)[1]', 'int') AS ErrNo ,t.e.value('(data[@name="severity"]/value)[1]', 'int') AS Severity ,t.e.value('(data[@name="message"]/value)[1]', 'varchar(max)') AS ErrMsg ,t.e.value('(action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text FROM @x.nodes('//RingBufferTarget/event') AS t(e) WHERE t.e.value('@name', 'varchar(50)') = 'error_reported'
650) this.width=650;" title="clip_image004" style="max-width:90%" alt="clip_image004" border="0" style="max-width:90%" />
对于system_health最有帮助的用途之一是跟踪死锁。对于目标ringbuffer,存储多少数据依赖于被监控机器上的该目标的容量,以及产生最大数量的设置相关,这些将在每个会话的定义中。你可以在system_health会话的输出中找到过去的死锁记录。
所有查询都会在system_health输出中,可以通过运行下面的代码获得一个死锁报表。
-- SQL Server 2008 R2 WITH SystemHealth AS ( SELECT CAST(target_data as xml) AS TargetData FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE name = 'system_health' AND st.target_name = 'ring_buffer') SELECT XEventData.XEvent.value('@timestamp','datetime')as Creation_Date,CAST(XEventData.XEvent.value('(data/value)[1]','VARCHAR(MAX)') AS XML) AS DeadLockGraph FROM SystemHealth CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData (XEvent) WHERE XEventData.XEvent.value('@name','varchar(4000)') = 'xml_deadlock_report' ORDER BY Creation_Date DESC
650) this.width=650;" title="clip_image005" style="max-width:90%" alt="clip_image005" border="0" style="max-width:90%" />
<deadlock> <victim-list> <victimProcess id="process14df44748" /> </victim-list> <process-list> <process id="process14df44748" taskpriority="0" logused="0" waitresource="KEY: 5:72057594297647104 (25d29b0b697a)" waittime="2417" ownerId="12672266142" transactionname="FETCH CURSOR" lasttranstarted="2014-12-10T13:21:31.360" XDES="0x8005b920" lockMode="S" schedulerid="7" kpid="3700" status="suspended" spid="130" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2014-12-10T13:21:00.133" lastbatchcompleted="2014-12-10T13:21:00.133" clientapp="SQLAgent - TSQL JobStep (Job 0xD7D593D56AA41A45B878CDD0BE6EEC79 : Step 1)" hostname="SZSQL01" hostpid="2604" loginname="WMS" isolationlevel="read committed (2)" xactid="12672266142" currentdb="5" lockTimeout="4294967295" clientoption1="673316896" clientoption2="128056"> <executionStack> <frame procname="" line="128" stmtstart="7494" stmtend="7632" sqlhandle="0x0300050099c38b5d87698c00659f00000100000000000000" /> <frame procname="" line="240" stmtstart="16044" stmtend="16204" sqlhandle="0x0300050063e39f5eec9c8501a19f00000100000000000000" /> <frame procname="" line="457" stmtstart="35402" stmtend="35694" sqlhandle="0x03000500ab05e430a8c2550148a200000100000000000000" /> <frame procname="" line="542" stmtstart="37436" stmtend="38776" sqlhandle="0x03000500622bc26d4be30101bf9f00000100000000000000" /> <frame procname="" line="80" stmtstart="5236" stmtend="5464" sqlhandle="0x030005009d864d5cf36f1401d5a300000100000000000000" /> <frame procname="" line="2" stmtstart="4" sqlhandle="0x0100050082ce6918f0cd5f69020000000000000000000000" /> </executionStack> <inputbuf> Exec SPSO_UrgentOrder_Allocation 'C','SYSTEM','' </inputbuf> </process> <process id="process9062508" taskpriority="0" logused="1172" waitresource="KEY: 5:72057594298040320 (a0d5874b4f9e)" waittime="2417" ownerId="12672266145" transactionname="DELETE" lasttranstarted="2014-12-10T13:21:31.360" XDES="0xc1a633c0" lockMode="X" schedulerid="10" kpid="6728" status="suspended" spid="74" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2014-12-10T13:21:27.530" lastbatchcompleted="2014-12-10T13:21:27.527" clientapp="jTDS" hostname="UNKNOWN" hostpid="123" loginname="WMS" isolationlevel="read committed (2)" xactid="12672266145" currentdb="5" lockTimeout="4294967295" clientoption1="673316896" clientoption2="128056"> <executionStack> <frame procname="" line="123" stmtstart="7034" stmtend="7406" sqlhandle="0x0300050099c38b5d87698c00659f00000100000000000000" /> <frame procname="" line="240" stmtstart="16044" stmtend="16204" sqlhandle="0x0300050063e39f5eec9c8501a19f00000100000000000000" /> <frame procname="" line="457" stmtstart="35402" stmtend="35694" sqlhandle="0x03000500ab05e430a8c2550148a200000100000000000000" /> <frame procname="" line="542" stmtstart="37436" stmtend="38776" sqlhandle="0x03000500622bc26d4be30101bf9f00000100000000000000" /> </executionStack> <inputbuf> Proc [Database Id = 5 Object Id = 1841441634] </inputbuf> </process> </process-list> <resource-list> <keylock hobtid="72057594297647104" dbid="5" objectname="" indexname="" id="lock486c0f580" mode="X" associatedObjectId="72057594297647104"> <owner-list> <owner id="process9062508" mode="X" /> </owner-list> <waiter-list> <waiter id="process14df44748" mode="S" requestType="wait" /> </waiter-list> </keylock> <keylock hobtid="72057594298040320" dbid="5" objectname="" indexname="" id="lock5520aee00" mode="S" associatedObjectId="72057594298040320"> <owner-list> <owner id="process14df44748" mode="S" /> </owner-list> <waiter-list> <waiter id="process9062508" mode="X" requestType="wait" /> </waiter-list> </keylock> </resource-list> </deadlock>
-- SQL Server 2012 WITH SystemHealth AS ( SELECT CAST(target_data as xml) AS TargetData FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE name = 'system_health' AND st.target_name = 'ring_buffer') SELECT XEventData.XEvent.value('@timestamp','datetime')as Creation_Date, XEventData.XEvent.query('(data/value/deadlock)[1]') AS DeadLockGraph FROM SystemHealth CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData (XEvent) WHERE XEventData.XEvent.value('@name','varchar(4000)') = 'xml_deadlock_report' ORDER BY Creation_Date DESC
650) this.width=650;" title="clip_image006" style="max-width:90%" alt="clip_image006" border="0" style="max-width:90%" />
<deadlock> <victim-list> <victimProcess id="process2b17a4558" /> </victim-list> <process-list> <process id="process2b17a4558" taskpriority="0" logused="672" waitresource="KEY: 5:72057594043826176 (286fc18d83ea)" waittime="6162" ownerId="7084361" transactionname="user_transaction" lasttranstarted="2015-01-06T10:48:42.090" XDES="0x2b6c1d6a8" lockMode="S" schedulerid="2" kpid="1624" status="suspended" spid="63" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2015-01-06T10:48:42.090" lastbatchcompleted="2015-01-06T10:45:25.407" lastattention="1900-01-01T00:00:00.407" clientapp="Microsoft SQL Server Management Studio - Query" hostname="WIN-LLPKR5BUV6S" hostpid="4712" loginname="WIN-LLPKR5BUV6S\Administrator" isolationlevel="read committed (2)" xactid="7084361" currentdb="5" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200"> <executionStack> <frame procname="adhoc" line="6" stmtstart="24" sqlhandle="0x020000002d83010497edc81695b0146b2f0000b7b2d28d190000000000000000000000000000000000000000"> SELECT * FROM [Person].[Address] WHERE [AddressID]=@1 </frame> <frame procname="adhoc" line="6" stmtstart="298" sqlhandle="0x02000000ab47741a8c9b1c9d67d523f9675a2ccfdcfc4fd10000000000000000000000000000000000000000"> SELECT * FROM Person.Address WHERE AddressID = 20 </frame> </executionStack> <inputbuf> --Window 2 USE AdventureWorks2012 BEGIN TRAN UPDATE Person.Address SET AddressLine1 = 'New address' WHERE AddressID = 25 WAITFOR DELAY '0:0:30' SELECT * FROM Person.Address WHERE AddressID = 20 </inputbuf> </process> <process id="process2b986d868" taskpriority="0" logused="6288" waitresource="KEY: 5:72057594043826176 (b81181109ebc)" waittime="4852" ownerId="7078917" transactionname="user_transaction" lasttranstarted="2015-01-06T10:35:45.447" XDES="0x2bd04f078" lockMode="S" schedulerid="2" kpid="3064" status="suspended" spid="61" sbid="0" ecid="0" priority="0" trancount="3" lastbatchstarted="2015-01-06T10:48:43.400" lastbatchcompleted="2015-01-06T10:45:25.407" lastattention="1900-01-01T00:00:00.407" clientapp="Microsoft SQL Server Management Studio - Query" hostname="WIN-LLPKR5BUV6S" hostpid="4712" loginname="WIN-LLPKR5BUV6S\Administrator" isolationlevel="read committed (2)" xactid="7078917" currentdb="5" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200"> <executionStack> <frame procname="adhoc" line="6" stmtstart="24" sqlhandle="0x020000002d83010497edc81695b0146b2f0000b7b2d28d190000000000000000000000000000000000000000"> SELECT * FROM [Person].[Address] WHERE [AddressID]=@1 </frame> <frame procname="adhoc" line="6" stmtstart="296" sqlhandle="0x02000000ea66c804b69860bd70b44e12bc27b94558e83d010000000000000000000000000000000000000000"> SELECT * FROM Person.Address WHERE AddressID = 25 </frame> </executionStack> <inputbuf> --Window1 USE AdventureWorks2012 BEGIN TRAN UPDATE Person.Address SET AddressLine1 = 'New address' WHERE AddressID = 20 WAITFOR DELAY '0:0:30' SELECT * FROM Person.Address WHERE AddressID = 25 </inputbuf> </process> </process-list> <resource-list> <keylock hobtid="72057594043826176" dbid="5" objectname="AdventureWorks2012.Person.Address" indexname="1" id="lock2ac70b500" mode="X" associatedObjectId="72057594043826176"> <owner-list> <owner id="process2b986d868" mode="X" /> </owner-list> <waiter-list> <waiter id="process2b17a4558" mode="S" requestType="wait" /> </waiter-list> </keylock> <keylock hobtid="72057594043826176" dbid="5" objectname="AdventureWorks2012.Person.Address" indexname="1" id="lock2b992b200" mode="X" associatedObjectId="72057594043826176"> <owner-list> <owner id="process2b17a4558" mode="X" /> </owner-list> <waiter-list> <waiter id="process2b986d868" mode="S" requestType="wait" /> </waiter-list> </keylock> </resource-list> </deadlock>
查看process-list的inputbuf子元素,可以看到导致死锁的代码片段,process-list显示所有死锁参与者的进程ID。process元素包含spid、数据库id、登录名、隔离级别、客户端应用程序名。Resource-list元素包含在死锁中的资源。查看owner-list和waiter-list元素可以看到这两个进程如何互相阻塞。
尝试将该XML的输出保存为XDL文档,用SSMS打开异常。目前有两个选择可以以图形方式打开死锁图表:SQL Sentry Plan Explorer Pro 和 SQL Server 2012 Management Studio,详见:https://www.sqlskills.com/blogs/jonathan/graphically-viewing-extended-events-deadlock-graphs/

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

For objects with the same name that already exist in the SQL Server database, the following steps need to be taken: Confirm the object type (table, view, stored procedure). IF NOT EXISTS can be used to skip creation if the object is empty. If the object has data, use a different name or modify the structure. Use DROP to delete existing objects (use caution, backup recommended). Check for schema changes to make sure there are no references to deleted or renamed objects.

The import steps are as follows: Copy the MDF file to SQL Server's data directory (usually C:\Program Files\Microsoft SQL Server\MSSQL\DATA). In SQL Server Management Studio (SSMS), open the database and select Attach. Click the Add button and select the MDF file. Confirm the database name and click the OK button.

When the SQL Server service fails to start, here are some steps to resolve: Check the error log to determine the root cause. Make sure the service account has permission to start the service. Check whether dependency services are running. Disable antivirus software. Repair SQL Server installation. If the repair does not work, reinstall SQL Server.

To view the SQL Server port number: Open SSMS and connect to the server. Find the server name in Object Explorer, right-click it and select Properties. In the Connection tab, view the TCP Port field.

SQL Server database files are usually stored in the following default location: Windows: C:\Program Files\Microsoft SQL Server\MSSQL\DATALinux: /var/opt/mssql/data The database file location can be customized by modifying the database file path setting.

If you accidentally delete a SQL Server database, you can take the following steps to recover: stop database activity; back up log files; check database logs; recovery options: restore from backup; restore from transaction log; use DBCC CHECKDB; use third-party tools. Please back up your database regularly and enable transaction logging to prevent data loss.

If the SQL Server installation fails, you can clean it up by following these steps: Uninstall SQL Server Delete registry keys Delete files and folders Restart the computer

SQL Server English installation can be changed to Chinese by following the following steps: download the corresponding language pack; stop the SQL Server service; install the language pack; change the instance language; change the user interface language; restart the application.
