{"id":559,"date":"2010-12-05T22:22:00","date_gmt":"2010-12-05T22:22:00","guid":{"rendered":"\/blogs\/jonathan\/post\/An-XEvent-a-Day-(5-of-31)-Targets-Week-e28093-ring_buffer.aspx"},"modified":"2017-04-13T12:17:46","modified_gmt":"2017-04-13T16:17:46","slug":"extended-events-ring_buffer","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/","title":{"rendered":"Extended Events Series (5 of 31) &#8211; Targets Week &#8211; ring_buffer"},"content":{"rendered":"<p>Yesterday\u2019s post, <a href=\"https:\/\/www.sqlskills.com\/blogs\/jonathan\/an-xevent-a-day-4-of-31-querying-the-session-definition-and-active-session-dmvs\/\" target=\"_blank\">Querying the Session Definition and Active Session DMV\u2019s<\/a>, showed how to find information about the Event Sessions that exist inside a SQL Server and how to find information about the Active Event Sessions that are running inside a SQL Server using the Session Definition and Active Session DMV\u2019s.\u00a0 With the background information now out of the way, and since this post falls on the start of a new week I\u2019ve decided to make this Targets Week, where each day we\u2019ll look at a different target in Extended Events starting with the ring_buffer today.<\/p>\n<h2>What is the ring_buffer?<\/h2>\n<p>The ring_buffer is one of two targets available in Extended Events that captures event data in its raw format.\u00a0 The ring_buffer is a memory resident target that holds event data in a single XML document while the Event Session is active on the SQL Server.\u00a0 When the Event Session is stopped, the memory buffers allocated to the ring_buffer target are freed and all data contained in the target disappears.\u00a0 The ring_buffer collects events in a First In First Out (FIFO) manner that can be configured to be strict, where the oldest event is removed when the memory allocated to the target become full and new events arrive, or per event, allowing you to specify the maximum number of occurrences that will be retained for each event defined in the event session.\u00a0 The default configuration for event flushing is strict FIFO.<\/p>\n<h2>Configuration Options<\/h2>\n<p>The ring_buffer like most of the targets has configuration options that can be found in the sys.dm_xe_object_columns DMV.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n-- Target Configurable Fields\r\nSELECT \r\n    oc.name AS column_name,\r\n    oc.column_id,\r\n    oc.type_name,\r\n    oc.capabilities_desc,\r\n    oc.description\r\nFROM sys.dm_xe_packages AS p\r\nINNER JOIN sys.dm_xe_objects AS o \r\n    ON p.guid = o.package_guid\r\nINNER JOIN sys.dm_xe_object_columns AS oc \r\n    ON o.name = oc.OBJECT_NAME \r\n    AND o.package_guid = oc.object_package_guid\r\nWHERE (p.capabilities IS NULL OR p.capabilities &amp; 1 = 0)\r\n  AND (o.capabilities IS NULL OR o.capabilities &amp; 1 = 0)\r\n  AND o.object_type = N'target'\r\n  AND o.name = N'ring_buffer';\r\n<\/pre>\n<p>In SQL Server 2008, 2008R2, and SQL Server Denali CTP1, the configuration options for the ring buffer are the max_memory option, which sets the maximum amount of memory to be used by the target buffers to hold Event data, and the occurrence_number, which is used to configure the FIFO operation of the target per Event, specifying the number of events by type that the target will retain.<\/p>\n<p><a href=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/212b1cfa\/image.png\"><img decoding=\"async\" style=\"display: inline; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png\" width=\"644\" height=\"49\" border=\"0\" \/><\/a><\/p>\n<p>Both of the configurable options for the ring_buffer target are optional, and when they are not specified as a part of the Event Session definition, they take on their default values.\u00a0 As previously stated, the default configuration for the ring_buffer is to use strict FIFO if no value is specified for the occurrence_number in the Event Session.\u00a0 The default max_memory value is 4MB for the ring_buffer, which is covered in slightly more detail in the Considerations for Usage section of this post.<\/p>\n<h2>Understanding the Target Data Format<\/h2>\n<p>As previously mentioned, the ring_buffer stores Event data in its raw format.\u00a0 Inside the Extended Events Engine, the Event data is maintained in a binary format that minimizes the amount of memory necessary to store the Events, maximizing the number of Events that can be stored inside the Targets memory buffers.\u00a0 The Event data is materialized into an XML document when the Target information is queried using the sys.dm_xe_session_targets DMV, allowing it to be used for Event analysis.\u00a0 The ring_buffer XML document contains a parent XML &lt;RingBufferTarget&gt; Node that contains attributes about the Targets operation since the Event Session was started including the number of Events processed per second, the amount of time the Target has spent processing Events, the total number of Events that have been processed by the Target, the current number of Events in the target, the number of Events dropped due to full buffers, and the amount of memory used by the Target.<\/p>\n<pre class=\"brush: xml; gutter: false; title: ; notranslate\" title=\"\">\r\n&lt;RingBufferTarget eventsPerSec=&quot;&quot; processingTime=&quot;&quot; totalEventsProcessed=&quot;&quot; eventCount=&quot;&quot; droppedCount=&quot;&quot; memoryUsed=&quot;&quot; \/&gt; \r\n<\/pre>\n<p>Inside of the &lt;RingBufferTarget&gt; parent node, are the Event data XML nodes which contain the information returned by the Events defined in the Event Session.\u00a0 While the XML returned for the Event data does not conform to any published XML Schema, it does have a predictable format based on the Event Session definition.\u00a0 The root &lt;event&gt; node contains attributes for the Event name, the Package that loaded the Event metadata and that fired the Event for the Event Session, an id associated with the Event, a version associated with the Event, and the timestamp for the date and time in GMT that the Event fired on the server.\u00a0 Each &lt;event&gt; node will have one or more &lt;data&gt; nodes that contain the information for each of the Event Data Elements returned by the Events default payload.\u00a0 If Actions have been defined for the Event in the Event Session the &lt;event&gt; node will have an &lt;action&gt; node for each of the Actions that were added to the Event.<\/p>\n<p>The &lt;data&gt; nodes and &lt;action&gt; nodes share a common XML schema, with one exception.\u00a0 These &lt;data&gt; nodes contain a single attribute containing the name of the Data Element contained by that node, whereas the &lt;action&gt; nodes contain two attributes; one containing the name of the Action contained by that node, and the other the Package for the Action.\u00a0 Each &lt;data&gt; or &lt;action&gt; node will have a &lt;type&gt; node that contains two attributes; the name of the Type for data type of the value being returned by the parent node, and the Package for the Type.\u00a0 The &lt;data&gt; or &lt;action&gt; node will also have two additional nodes; a &lt;value&gt; node which contains the value for the data being returned in the Data Element, and a &lt;text&gt; node which will contain the Map lookup text for Data Elements that correspond to Maps in the Extended Events Metadata.\u00a0 The basic XML definition of an &lt;event&gt; node would be:<\/p>\n<pre class=\"brush: xml; gutter: false; title: ; notranslate\" title=\"\">\r\n&lt;event name=&quot;&quot; package=&quot;&quot; id=&quot;&quot; version=&quot;&quot; timestamp=&quot;&quot;&gt;\r\n  &lt;data name=&quot;&quot;&gt;\r\n    &lt;type name=&quot;&quot; package=&quot;&quot; \/&gt;\r\n    &lt;value \/&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/data&gt;\r\n  &lt;action name=&quot;&quot; package=&quot;&quot;&gt;\r\n    &lt;type name=&quot;&quot; package=&quot;&quot; \/&gt;\r\n    &lt;value \/&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/action&gt;\r\n&lt;\/event&gt;\r\n<\/pre>\n<p>Below is an example Event from the default system_health Event Session that is running on every installation of SQL Server 2008, and SQL Server Denali CTP1 for the wait_info Event.<\/p>\n<pre class=\"brush: xml; gutter: false; title: ; notranslate\" title=\"\">\r\n&lt;event name=&quot;wait_info&quot; package=&quot;sqlos&quot; id=&quot;48&quot; version=&quot;1&quot; timestamp=&quot;2010-12-03T15:29:00.578Z&quot;&gt;\r\n  &lt;data name=&quot;wait_type&quot;&gt;\r\n    &lt;type name=&quot;wait_types&quot; package=&quot;sqlos&quot; \/&gt;\r\n    &lt;value&gt;98&lt;\/value&gt;\r\n    &lt;text&gt;ASYNC_IO_COMPLETION&lt;\/text&gt;\r\n  &lt;\/data&gt;\r\n  &lt;data name=&quot;opcode&quot;&gt;\r\n    &lt;type name=&quot;event_opcode&quot; package=&quot;sqlos&quot; \/&gt;\r\n    &lt;value&gt;1&lt;\/value&gt;\r\n    &lt;text&gt;End&lt;\/text&gt;\r\n  &lt;\/data&gt;\r\n  &lt;data name=&quot;duration&quot;&gt;\r\n    &lt;type name=&quot;uint64&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;44598&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/data&gt;\r\n  &lt;data name=&quot;max_duration&quot;&gt;\r\n    &lt;type name=&quot;uint64&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;44598&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/data&gt;\r\n  &lt;data name=&quot;total_duration&quot;&gt;\r\n    &lt;type name=&quot;uint64&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;44598&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/data&gt;\r\n  &lt;data name=&quot;signal_duration&quot;&gt;\r\n    &lt;type name=&quot;uint64&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;0&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/data&gt;\r\n  &lt;data name=&quot;completed_count&quot;&gt;\r\n    &lt;type name=&quot;uint64&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;1&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/data&gt;\r\n  &lt;action name=&quot;callstack&quot; package=&quot;package0&quot;&gt;\r\n    &lt;type name=&quot;callstack&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;0x0000000001829555\r\n0x0000000000CEA584\r\n0x000000000233FA28\r\n0x0000000002E2FA0C\r\n0x0000000002F10CB9\r\n0x0000000002F112D7\r\n0x0000000002F1B90B\r\n0x0000000002D8C59A\r\n0x0000000000B0F6D2\r\n0x000000000065C59B\r\n0x000000000065C25A\r\n0x000000000065BF35\r\n0x0000000000BE6410\r\n0x0000000000BE64E0\r\n0x0000000000BD87A0\r\n0x0000000000BE5F9F&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/action&gt;\r\n  &lt;action name=&quot;session_id&quot; package=&quot;sqlserver&quot;&gt;\r\n    &lt;type name=&quot;uint16&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;87&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/action&gt;\r\n  &lt;action name=&quot;sql_text&quot; package=&quot;sqlserver&quot;&gt;\r\n    &lt;type name=&quot;unicode_string&quot; package=&quot;package0&quot; \/&gt;\r\n    &lt;value&gt;Unable to retrieve SQL text&lt;\/value&gt;\r\n    &lt;text \/&gt;\r\n  &lt;\/action&gt;\r\n&lt;\/event&gt;\r\n<\/pre>\n<p>In this Event, the wait_type and opcode Data Elements correspond to the Maps wait_types and opcode respectively, and the text value for the Map that corresponds to the &lt;value&gt; node is in the &lt;text&gt; node.\u00a0 It is possible to lookup the Maps in the DMV\u2019s separately though not necessary in this example as follows:<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT \r\n    p.name AS package_name,\r\n    mv.name AS map_name,\r\n    mv.map_key,\r\n    mv.map_value\r\nFROM sys.dm_xe_packages p\r\nJOIN sys.dm_xe_map_values mv \r\nON p.guid = mv.object_package_guid\r\nWHERE (p.name = 'sqlos' AND mv.name = 'wait_types')\r\n   OR (p.name = 'sqlos' AND mv.name = 'event_opcode') ;\r\n<\/pre>\n<h2>Querying\/Parsing the Target Data<\/h2>\n<p>Since the ring_buffer target returns the Event data as XML, obviously we are going to have to do a little bit of work to shred the XML into actionable data using XQuery.\u00a0 For those new to XQuery, the best I can recommend is to jump over to my good friend Jacob Sebastian\u2019s blog and work your way through his series of <a href=\"http:\/\/beyondrelational.com\/modules\/2\/blogs\/28\/posts\/10279\/xquery-labs-a-collection-of-xquery-sample-scripts.aspx\" target=\"_blank\">XQuery Labs<\/a>, which have been an amazing resource along my way to learning XQuery.\u00a0 If you are not interested in learning XQuery, but still want to work with Extended Events, all is not lost.\u00a0 Adam Machanic wrote the <a href=\"http:\/\/sqlblog.com\/blogs\/adam_machanic\/archive\/2010\/05\/08\/extended-events-code-generator-v1-001-a-quick-fix.aspx\" target=\"_blank\">Extended Events Code Generator<\/a>, which you can use to generate a TSQL statement that will parse out the target data for the ring_buffer, as well as for tomorrows topic, the asynchronous_file_target.\u00a0 It also includes a SQLCLR helper TVF that optimizes shredding the XML by leveraging the power of .NET that you can optionally deploy in your environment.\u00a0 Another option is to use the <a href=\"http:\/\/extendedeventmanager.codeplex.com\/\" target=\"_blank\">Extended Events SSMS Addin for SQL Server 2008<\/a> which includes a TargetDataViewer that shreds the XML for every target available in Extended Events and displays the Event data in a SQL Profiler like GridView inside of SQL Server Management Studio.\u00a0 Beyond these two tools, you can also use the code available in this blog series.<\/p>\n<p>One of the nuances of working with XML inside of SQL Server, especially with Extended Events, is that sometimes it is better for performance to use a XML variable to hold the XML data for shredding, rather than attempting to shred the XML directly from the DMV\u2019s.\u00a0 I\u2019ve never quite figured out why this is the case, but it tends to make a bigger impact on larger XML documents, specifically those in the 2MB+ size range.<\/p>\n<p>Since every server running SQL Server 2008, 2008R2, or Denali CTP1 has the system_health session running by default in it, I am going to use that event session to demonstrate how to query the information from the ring_buffer target.\u00a0 To get the Target data into an XML variable, we\u2019ll need to query the target_data column of the sys.dm_xe_session_targets DMV and CAST the value returned to the XML data type.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nDECLARE @target_data XML;\r\nSELECT @target_data = CAST(target_data AS XML)\r\nFROM sys.dm_xe_sessions AS s \r\nJOIN sys.dm_xe_session_targets AS t \r\n    ON t.event_session_address = s.address\r\nWHERE s.name = N'system_health';\r\n<\/pre>\n<p>With that variable, we can then parse out the Targets header information from the &lt;RingBufferTarget&gt; node attributes:<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT \r\n    @target_data.value('(RingBufferTarget\/@eventsPerSec)&#x5B;1]', 'int') AS eventsPerSec,\r\n    @target_data.value('(RingBufferTarget\/@processingTime)&#x5B;1]', 'int') AS processingTime,\r\n    @target_data.value('(RingBufferTarget\/@totalEventsProcessed)&#x5B;1]', 'int') AS totalEventsProcessed,\r\n    @target_data.value('(RingBufferTarget\/@eventCount)&#x5B;1]', 'int') AS eventCount,\r\n    @target_data.value('(RingBufferTarget\/@droppedCount)&#x5B;1]', 'int') AS droppedCount,\r\n    @target_data.value('(RingBufferTarget\/@memoryUsed)&#x5B;1]', 'int') AS memoryUsed;\r\n<\/pre>\n<p>We can also parse out the individual &lt;event&gt; data nodes from the Target data by using .nodes() method and specifying the XPath to the event nodes and then using .query() method to materialize each node returned by .nodes() as a separate XML document for output.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT \r\n    n.query('.') AS event_data\r\nFROM @target_data.nodes('RingBufferTarget\/event') AS q(n);\r\n<\/pre>\n<p>We can also use an XPath filter in the .nodes() method to query specific Events only<\/p>\n<p><strong>(Note: if your server hasn\u2019t encountered waits that exceed the predicates for the system_health session, this query will not return results).<\/strong><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT \r\n    n.query('.') AS event_data\r\nFROM @target_data.nodes('RingBufferTarget\/event&#x5B;@name=''wait_info'']') AS q(n);\r\n<\/pre>\n<p>Building on this, we can shred the &lt;event&gt; nodes for the wait_info Events based on the Event definition in the Event Session to turn the XML data into a tabular output that is easier to read.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT \r\n    n.value('(@name)&#x5B;1]', 'varchar(50)') AS event_name,\r\n    n.value('(@package)&#x5B;1]', 'varchar(50)') AS package_name,\r\n    n.value('(@id)&#x5B;1]', 'int') AS id,\r\n    n.value('(@version)&#x5B;1]', 'int') AS version,\r\n    DATEADD(hh, \r\n            DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP), \r\n            n.value('(@timestamp)&#x5B;1]', 'datetime2')) AS &#x5B;timestamp],\r\n    n.value('(data&#x5B;@name=&quot;wait_type&quot;]\/text)&#x5B;1]', 'varchar(250)') as wait_type,\r\n    n.value('(data&#x5B;@name=&quot;opcode&quot;]\/text)&#x5B;1]', 'varchar(250)') as opcode,\r\n    n.value('(data&#x5B;@name=&quot;duration&quot;]\/value)&#x5B;1]', 'bigint') as duration,\r\n    n.value('(data&#x5B;@name=&quot;max_duration&quot;]\/value)&#x5B;1]', 'bigint') as max_duration,\r\n    n.value('(data&#x5B;@name=&quot;total_duration&quot;]\/value)&#x5B;1]', 'bigint') as total_duration,\r\n    n.value('(data&#x5B;@name=&quot;completed_count&quot;]\/value)&#x5B;1]', 'bigint') as completed_count,\r\n    n.value('(action&#x5B;@name=&quot;callstack&quot;]\/value)&#x5B;1]', 'varchar(max)') as callstack,\r\n    n.value('(action&#x5B;@name=&quot;session_id&quot;]\/value)&#x5B;1]', 'int') as session_id,\r\n    n.value('(action&#x5B;@name=&quot;sql_text&quot;]\/value)&#x5B;1]', 'varchar(max)') as sql_text\r\nFROM @target_data.nodes('RingBufferTarget\/event&#x5B;@name=''wait_info'']') AS q(n);\r\n<\/pre>\n<p>Now we could do a lot more actionable work with this data by turning this query into a derived table, or changing it to be a SELECT INTO a temporary table that we query a number of other ways after shredding the XML information.\u00a0 I\u2019ll leave the possibilities for how to consume this data after shredding the XML up to your imagination, and for another post in this series.<\/p>\n<h2>Considerations for Usage<\/h2>\n<p>While the ring_buffer target may seem like the ideal Target for short term analysis, there are a number of considerations that must be made in determining whether or not it is the correct Target to use in an Event Session.\u00a0 The first of these is the number of Events that the Target can actually hold based on the max_memory.\u00a0 If the Event Session is expected to generate a large quantity of Events, the ring_buffer will probably not meet your needs, depending on the Events definitions in the Event Session.\u00a0 In addition to this consideration, there is a known issue related to the ring_buffer Target associated with it returning XML through the sys.dm_xe_session_targets DMV as discussed by Bob Ward in his blog post: <a title=\"http:\/\/blogs.msdn.com\/b\/psssql\/archive\/2009\/09\/17\/you-may-not-see-the-data-you-expect-in-extended-event-ring-buffer-targets.aspx\" href=\"https:\/\/blogs.msdn.microsoft.com\/b\/psssql\/archive\/2009\/09\/17\/you-may-not-see-the-data-you-expect-in-extended-event-ring-buffer-targets.aspx\" target=\"_blank\">You may not see the data you expect in Extended Event Ring Buffer Targets\u2026.<\/a>\u00a0 Essentially, the DMV can only return 4MB of materialized XML, which becomes problematic for a Target that is defined to retain 4MB of Event data in binary form.\u00a0 The binary representation of the Event data can easily exceed 4MB when materialized as XML for the DMV to output.\u00a0 When this occurs the output from the DMV is a malformed XML document, as detailed in the <a href=\"https:\/\/connect.microsoft.com:443\/SQLServer\/feedback\/details\/432548\/extended-events-ringbuffer-partial-event-data-when-ringbuffer-is-full\" target=\"_blank\">Connect item<\/a> referenced in Bob\u2019s blog post.\u00a0 According to the the Connect item, this problem has been addressed in <a href=\"http:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=12548\" target=\"_blank\">SQL Server 2008 Service Pack 2<\/a>.\u00a0 In addition to this issue, Adam Machanic filed a slightly different <a href=\"https:\/\/connect.microsoft.com\/SQLServer\/feedback\/details\/433859\/xe-ring-buffer-target-does-not-show-all-collected-events\" target=\"_blank\">Connect item<\/a> regarding the failure of the ring_buffer target to return all of the Events captured, which according to the feedback comments is also fixed in <a href=\"http:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=12548\" target=\"_blank\">SQL Server 2008 Service Pack 2<\/a> and <a href=\"https:\/\/support.microsoft.com\/kb\/981355\" target=\"_blank\">SQL Server 2008 R2 Cumulative Update 1<\/a>.<\/p>\n<p>One of the other considerations for using the ring_buffer Target is that the information captured by an Event Session is memory resident only.\u00a0 This means that if you are capturing Events in the Event Session that are critical and require persistence in the event of that the SQL Server instance encounters a crash the information captured by the target will not be available when the SQL Server instance restarts.\u00a0 However, when you are doing analysis of a specific workload while the server is online and available, the ring_buffer can still be useful for capturing Events specific to the workload being analyzed.\u00a0 To accommodate this, and capture Events and maintain them in a static nature without performing a DROP SESSION on the Event Session, it is necessary to remove the Events from the Event Session by performing an ALTER EVENT SESSION in conjunction with the DROP EVENT DDL command.\u00a0 To demonstrate this, we can create an Event Session that captures the error_reported Event.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n-- Create an Event Session to capture Errors Reported\r\nCREATE EVENT SESSION DemoPersistedEvents\r\nON SERVER\r\nADD EVENT sqlserver.error_reported\r\nADD TARGET package0.ring_buffer\r\nWITH (MAX_DISPATCH_LATENCY = 1 SECONDS);\r\nGO\r\n-- Alter the Event Session and Start it.\r\nALTER EVENT SESSION DemoPersistedEvents\r\nON SERVER\r\nSTATE=START;\r\nGO\r\n-- SELECT from a non-existent table to create Event\r\nSELECT *\r\nFROM master.schema_doesnt_exist.table_doesnt_exist;\r\nGO\r\n-- Drop the Event to halt Event collection\r\nALTER EVENT SESSION DemoPersistedEvents\r\nON SERVER\r\nDROP EVENT sqlserver.error_reported;\r\nGO\r\n-- Wait for Event buffering to Target\r\nWAITFOR DELAY '00:00:01';\r\nGO\r\n-- Create XML variable to hold Target Data\r\nDECLARE @target_data XML;\r\nSELECT @target_data = CAST(target_data AS XML)\r\nFROM sys.dm_xe_sessions AS s \r\nJOIN sys.dm_xe_session_targets AS t \r\n    ON t.event_session_address = s.address\r\nWHERE s.name = N'DemoPersistedEvents'\r\n  AND t.target_name = N'ring_buffer';\r\n\r\n-- Query XML variable to get Event Data\r\nSELECT \r\n    @target_data.value('(RingBufferTarget\/@eventsPerSec)&#x5B;1]', 'int') AS eventsPerSec,\r\n    @target_data.value('(RingBufferTarget\/@processingTime)&#x5B;1]', 'int') AS processingTime,\r\n    @target_data.value('(RingBufferTarget\/@totalEventsProcessed)&#x5B;1]', 'int') AS totalEventsProcessed,\r\n    @target_data.value('(RingBufferTarget\/@eventCount)&#x5B;1]', 'int') AS eventCount,\r\n    @target_data.value('(RingBufferTarget\/@droppedCount)&#x5B;1]', 'int') AS droppedCount,\r\n    @target_data.value('(RingBufferTarget\/@memoryUsed)&#x5B;1]', 'int') AS memoryUsed;\r\n\r\nSELECT \r\n    n.value('(@name)&#x5B;1]', 'varchar(50)') AS event_name,\r\n    n.value('(@package)&#x5B;1]', 'varchar(50)') AS package_name,\r\n    n.value('(@id)&#x5B;1]', 'int') AS id,\r\n    n.value('(@version)&#x5B;1]', 'int') AS version,\r\n    DATEADD(hh, \r\n            DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP), \r\n            n.value('(@timestamp)&#x5B;1]', 'datetime2')) AS &#x5B;timestamp],\r\n    n.value('(data&#x5B;@name=&quot;error&quot;]\/value)&#x5B;1]', 'int') as error,\r\n    n.value('(data&#x5B;@name=&quot;severity&quot;]\/value)&#x5B;1]', 'int') as severity,\r\n    n.value('(data&#x5B;@name=&quot;duration&quot;]\/value)&#x5B;1]', 'int') as state,\r\n    n.value('(data&#x5B;@name=&quot;user_defined&quot;]\/value)&#x5B;1]', 'varchar(5)') as user_defined,\r\n    n.value('(data&#x5B;@name=&quot;message&quot;]\/value)&#x5B;1]', 'varchar(max)') as message\r\nFROM @target_data.nodes('RingBufferTarget\/event') AS q(n);\r\nGO\r\n-- Drop the Event Session to cleanup Demo\r\nDROP EVENT SESSION DemoPersistedEvents\r\nON SERVER;\r\n<\/pre>\n<p>If your specific requirements allow for the loss of Events due to the FIFO nature of the ring_buffer Target, and you have applied the necessary patches to your SQL Server instance to ensure that invalid XML is not returned by the sys.dm_xe_session_targets DMV, the ring_buffer Target may provide the required functionality for your specific implementation.\u00a0 When using an Event Session in the short term, or an Event Session that is Predicated to minimize the number of Events that will actually be fired, the ring_buffer is a maintenance free method of collecting raw Event data for further analysis when the Events are dropped from the Event Session to ensure that unnecessary Events are not captured by the Event Session.<\/p>\n<h2><\/h2>\n<h2>What\u2019s next?<\/h2>\n<p>Now that we have looked at the ring_buffer Target, in the next post we\u2019ll look at the asynchronous_file_target which can be used to capture raw Event data into a persistent file in the Operating System allowing for long term Event analysis and capturing Events in a persistent manner that exists beyond SQL Server Instance failures and service restarts and in a manner than can be provided for external analysis similar to SQL Trace files.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday\u2019s post, Querying the Session Definition and Active Session DMV\u2019s, showed how to find information about the Event Sessions that exist inside a SQL Server and how to find information about the Active Event Sessions that are running inside a SQL Server using the Session Definition and Active Session DMV\u2019s.\u00a0 With the background information now [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,23,38,45],"tags":[],"class_list":["post-559","post","type-post","status-publish","format-standard","hentry","category-execution-plans","category-extended-events","category-sql-server-2008","category-xevent-a-day-series"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SQL Server Extended Events ring_buffer | Jonathan Kehayias<\/title>\n<meta name=\"description\" content=\"Demonstrates how to use the Extended Events ring_buffer target to collect data, the output XML format, and the configuration options for the target.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL Server Extended Events ring_buffer | Jonathan Kehayias\" \/>\n<meta property=\"og:description\" content=\"Demonstrates how to use the Extended Events ring_buffer target to collect data, the output XML format, and the configuration options for the target.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/\" \/>\n<meta property=\"og:site_name\" content=\"Jonathan Kehayias\" \/>\n<meta property=\"article:published_time\" content=\"2010-12-05T22:22:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-04-13T16:17:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png\" \/>\n<meta name=\"author\" content=\"Jonathan Kehayias\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jonathan Kehayias\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/\"},\"author\":{\"name\":\"Jonathan Kehayias\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#\\\/schema\\\/person\\\/01c10d94f3648654ef706d5e6305f69c\"},\"headline\":\"Extended Events Series (5 of 31) &#8211; Targets Week &#8211; ring_buffer\",\"datePublished\":\"2010-12-05T22:22:00+00:00\",\"dateModified\":\"2017-04-13T16:17:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/\"},\"wordCount\":3630,\"commentCount\":4,\"image\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windowslivewriter\\\/anxeventaday5of31targetsweekring_buffer\\\/6426eb67\\\/image_thumb.png\",\"articleSection\":[\"Execution Plans\",\"Extended Events\",\"SQL Server 2008\",\"XEvent a Day Series\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/\",\"url\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/\",\"name\":\"SQL Server Extended Events ring_buffer | Jonathan Kehayias\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windowslivewriter\\\/anxeventaday5of31targetsweekring_buffer\\\/6426eb67\\\/image_thumb.png\",\"datePublished\":\"2010-12-05T22:22:00+00:00\",\"dateModified\":\"2017-04-13T16:17:46+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#\\\/schema\\\/person\\\/01c10d94f3648654ef706d5e6305f69c\"},\"description\":\"Demonstrates how to use the Extended Events ring_buffer target to collect data, the output XML format, and the configuration options for the target.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windowslivewriter\\\/anxeventaday5of31targetsweekring_buffer\\\/6426eb67\\\/image_thumb.png\",\"contentUrl\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windowslivewriter\\\/anxeventaday5of31targetsweekring_buffer\\\/6426eb67\\\/image_thumb.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/extended-events-ring_buffer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Execution Plans\",\"item\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/category\\\/execution-plans\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Extended Events Series (5 of 31) &#8211; Targets Week &#8211; ring_buffer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#website\",\"url\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/\",\"name\":\"Jonathan Kehayias - The Rambling DBA\",\"description\":\"The Rambling DBA\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#\\\/schema\\\/person\\\/01c10d94f3648654ef706d5e6305f69c\",\"name\":\"Jonathan Kehayias\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g\",\"caption\":\"Jonathan Kehayias\"},\"sameAs\":[\"http:\\\/\\\/3.209.169.194\\\/blogs\\\/jonathan\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SQL Server Extended Events ring_buffer | Jonathan Kehayias","description":"Demonstrates how to use the Extended Events ring_buffer target to collect data, the output XML format, and the configuration options for the target.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/","og_locale":"en_US","og_type":"article","og_title":"SQL Server Extended Events ring_buffer | Jonathan Kehayias","og_description":"Demonstrates how to use the Extended Events ring_buffer target to collect data, the output XML format, and the configuration options for the target.","og_url":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/","og_site_name":"Jonathan Kehayias","article_published_time":"2010-12-05T22:22:00+00:00","article_modified_time":"2017-04-13T16:17:46+00:00","og_image":[{"url":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png","type":"","width":"","height":""}],"author":"Jonathan Kehayias","twitter_misc":{"Written by":"Jonathan Kehayias","Est. reading time":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#article","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/"},"author":{"name":"Jonathan Kehayias","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#\/schema\/person\/01c10d94f3648654ef706d5e6305f69c"},"headline":"Extended Events Series (5 of 31) &#8211; Targets Week &#8211; ring_buffer","datePublished":"2010-12-05T22:22:00+00:00","dateModified":"2017-04-13T16:17:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/"},"wordCount":3630,"commentCount":4,"image":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#primaryimage"},"thumbnailUrl":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png","articleSection":["Execution Plans","Extended Events","SQL Server 2008","XEvent a Day Series"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/","url":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/","name":"SQL Server Extended Events ring_buffer | Jonathan Kehayias","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#primaryimage"},"image":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#primaryimage"},"thumbnailUrl":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png","datePublished":"2010-12-05T22:22:00+00:00","dateModified":"2017-04-13T16:17:46+00:00","author":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#\/schema\/person\/01c10d94f3648654ef706d5e6305f69c"},"description":"Demonstrates how to use the Extended Events ring_buffer target to collect data, the output XML format, and the configuration options for the target.","breadcrumb":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#primaryimage","url":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png","contentUrl":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windowslivewriter\/anxeventaday5of31targetsweekring_buffer\/6426eb67\/image_thumb.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/extended-events-ring_buffer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/"},{"@type":"ListItem","position":2,"name":"Execution Plans","item":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/category\/execution-plans\/"},{"@type":"ListItem","position":3,"name":"Extended Events Series (5 of 31) &#8211; Targets Week &#8211; ring_buffer"}]},{"@type":"WebSite","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#website","url":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/","name":"Jonathan Kehayias - The Rambling DBA","description":"The Rambling DBA","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#\/schema\/person\/01c10d94f3648654ef706d5e6305f69c","name":"Jonathan Kehayias","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g","caption":"Jonathan Kehayias"},"sameAs":["http:\/\/3.209.169.194\/blogs\/jonathan"]}]}},"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/posts\/559","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/comments?post=559"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/posts\/559\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/media?parent=559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/categories?post=559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/tags?post=559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}