<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Using SQL Server Extended Events</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/extended_events/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/extended_events/feed.xml</link>
    <description>Discussions, examples and general news about SQL Server Extended Events from the team that built it.</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:20:31 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Extended Events demos on Microsoft Virtual Academy</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/extended-events-demos-on-microsoft-virtual-academy</link>
      <pubDate>Wed, 28 Mar 2012 14:31:00 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2012/03/28/extended-events-demos-on-microsoft-virtual-academy/</guid>
      <description><![CDATA[I had an opportunity recently to contribute a presentation to the Microsoft Virtual Academy as part...]]></description>
      <content:encoded><![CDATA[<p>I had an opportunity recently to contribute a presentation to the Microsoft Virtual Academy as part of the <a href="https://www.microsoftvirtualacademy.com/tracks/mission-critical-confidence-using-microsoft-sql-server-2012" target="_blank">Mission Critical Confidence using SQL Server 2012</a> course offering. The MVA offers you a myriad of free training opportunities, so I encourage anyone who is interested in expanding your knowledge to take advantage of this offering.</p>  <p>For those of you who don’t want to invest the time to go through the whole course, you can access my presentation <a href="http://technet.microsoft.com/en-us/edge/microsoft-virtual-academy-mission-critical-confidence-using-sql-server-2012-module-9-using-the-power-of-extended-events-for-tracing-and-troubleshooting.aspx" target="_blank">here</a>. I cover the following topics:</p>  <ul>   <li>Integration of Extended Events into AlwaysOn troubleshooting.</li>    <li>Troubleshooting Login failures using client/server correlation.</li>    <li>Troubleshooting query performance issues using client/server correlation.</li> </ul>  <p>I’m not sure how long content is made available on MVA, I got the impression that it would be removed as some point in the future, but should be there for at lease several months.</p>  <p>- Mike</p>]]></content:encoded>
    </item>
    <item>
      <title>Issues with the system_health session in SQL Server 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/issues-with-the-system_health-session-in-sql-server-2012</link>
      <pubDate>Fri, 17 Feb 2012 08:37:03 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2012/02/17/issues-with-the-system_health-session-in-sql-server-2012/</guid>
      <description><![CDATA[The ever alert Jonathan Kehayias (Blog | Twitter) sent me a question recently asking about the...]]></description>
      <content:encoded><![CDATA[<p>The ever alert Jonathan Kehayias (<a href="http://sqlskills.com/blogs/jonathan" target="_blank">Blog</a> | <a href="https://twitter.com/sqlsarg" target="_blank">Twitter</a>) sent me a question recently asking about the <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/13/introducing-the-extended-events-user-interface.aspx" target="_blank">Extended Event UI</a> used for showing predicates. In particular, he was wondering about the predicate for the wait_info event that is defined in the system_health session and was wondering what was going on.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/1780.wait_info_pred_129FB372.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/1780.wait_5F00_info_5F00_pred_5F00_129FB372.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="wait_info_pred" border="0" alt="wait_info_pred" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/7450.wait_info_pred_thumb_6150C911.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/7450.wait_5F00_info_5F00_pred_5F00_thumb_5F00_6150C911.jpg" width="347" height="343" /></a></p>  <p>It’s obvious what peaked Jonathan’s interest – all those error icons seem like there is a problem with the predicate. This post will explain what’s happening, why it’s happening and also document a problem that I discovered while investigating this and for which I will give you a solution.</p>  <h6>Bug or Artifact – You make the call</h6>  <p>I’d actually call this an artifact because the rows that have error icons are caused because of a change made somewhere else in SQL Server that result in the Filter UI not being able to resolve the integer value (map_key) we specify in the predicate to the name of an actual wait (map_value). The reason that the map_key cannot be resolved is because of changes made within SQL Server to the enumeration of our wait types. These changes don’t impact you directly, but it turns out they do mess with how our UI displays this filter. This is a little complex, but I’ll attempt to give you the short version…</p>  <p>In order to save space we’ve created a special data type in extended events called a map, which allows us to use an integer to represent some known value. (OK, this probably isn’t really that complex for all you DBAs since you do it all the time with PK/FK relationships and lookup tables.) We store these mappings in dm_xe_map_values and the UI uses this DMV to resolve the map_value when it displays the filter. The wait_type field in the wait_info event is one of these map data types. Let’s take a simple example, we might write a filter for wait_info such as:</p>  <blockquote>   <p><em>wait_type = 120</em></p> </blockquote>  <p>A quick check of dm_xe_map_values shows us that 120 is equivalent to the SOS_SCHEDULER_YIELD wait type, so the UI would display:</p>  <blockquote>   <p>wait_type | equal_uint64 | SOS_SCHEDULER_YIELD</p> </blockquote>  <p>In the case of wait_type we get this mapping directly from within the SQL Server engine (this is true of many maps) so any changes to the list of wait_types are automatically represented in our map DMV. The reason you see blanks in the Value field in some cases is because the list of wait_types is not always contiguous; in other words, there are gaps in the map_key list because there are some numbers that have not been used yet. The change I referenced earlier, is that the unused regions used to be filled with place holder values (PADDING_##) but are now just missing in SQL Server 2012. You can convince yourself of this very easily by running the following query:</p>  <blockquote>   <pre class="csharpcode"><span class="kwrd">SELECT</span> <span class="kwrd">TOP</span> 50 * <span class="kwrd">FROM</span> sys.dm_xe_map_value</pre>
</blockquote>


<p>What you’ll see is the following:</p>

<table border="0" cellspacing="0" cellpadding="2" width="400"><tbody>
    <tr>
      <td valign="top" width="200">
        <p align="center"><strong>map_keys</strong></p>
      </td>

      <td valign="top" width="200">
        <p align="center"><strong>values</strong></p>
      </td>
    </tr>

    <tr>
      <td valign="top" width="200">0</td>

      <td valign="top" width="200">UNKNOWN</td>
    </tr>

    <tr>
      <td valign="top" width="200">1-21</td>

      <td valign="top" width="200">Lock waits</td>
    </tr>

    <tr>
      <td valign="top" width="200">22-31</td>

      <td valign="top" width="200">Not used</td>
    </tr>

    <tr>
      <td valign="top" width="200">32-37</td>

      <td valign="top" width="200">Latch waits</td>
    </tr>

    <tr>
      <td valign="top" width="200">38-47</td>

      <td valign="top" width="200">Not used</td>
    </tr>

    <tr>
      <td valign="top" width="200">48-50</td>

      <td valign="top" width="200">Pagelatch waits</td>
    </tr>
  </tbody></table>

<p>In the system_health session we specify a filter that selects for the waits that we want to collect, but but instead of specifying each wait independently we specify ranges. So for example, to collect all the PAGELATCH* waits, we’d use this predicate:</p>

<pre class="csharpcode">(wait_type &gt; 47 <span class="kwrd">and</span> wait_type &lt; 54)</pre>


<p>But from the table earlier in the post we know that wait_type 47 is not used, so when the UI looks up the value for 47, it comes back empty, which it perceives to be an error and marks it as such. Logically, this in not an error because 48 &gt; 47 whether there happens to be a 47 in the list or not. The predicate still works, it’s just that the UI doesn’t know how to display it.</p>

<h6>You said there was an “issue”</h6>

<p>Yes I did, and thank you for reminding me.</p>

<p>While I was investigating the UI artifact I noticed that there have been several additions to the wait_type list, and a few deletions, in SQL Server 2012 that has resulted in significant renumbering of the wait_types map. This has had the unfortunate result of changing the meaning of the filter that we specified for both wait_info and wait_info_external, to the point where system_health is not longer collecting the waits we consider important. This is definitely a bug, but one that we won’t be able to address until after RTM. Since we can’t get the fix in for RTM, I’m providing a script that will correct the system_health session here.</p>

<p>This script will do the following:</p>

<ul>
  <li>If the system_health session exists, it will remove the wait_info &amp; wait_info_external events and replace them with the corrected filter. Any modifications you’ve made to these events in your system_health session will be lost. </li>

  <li>If the system_health session does not exist, it will created it. </li>

  <li>If the system_health session is not running, it will be started. </li>
</ul>



<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:aeaaaaa2-81a3-4425-9b6d-22b527f5273f" class="wlWriterEditableSmartContent"><p>Download the fix for the <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/0513.system_health_fixup_0E65B5E0.sql" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/0513.system_5F00_health_5F00_fixup_5F00_0E65B5E0.sql" target="_blank">system health session</a></p></div>]]></content:encoded>
    </item>
    <item>
      <title>Activity Tracking event session template is broken</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/activity-tracking-event-session-template-is-broken</link>
      <pubDate>Tue, 03 Jan 2012 08:20:46 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2012/01/03/activity-tracking-event-session-template-is-broken/</guid>
      <description><![CDATA[With the release of SQL Server 2012 RC0 you will notice that a number of new session templates have...]]></description>
      <content:encoded><![CDATA[<p>With the release of SQL Server 2012 RC0 you will notice that a number of new session templates have shown up in both the New Session Wizard and the New Session dialog. One template in particular, Activity Tracking, is unfortunately broken “out of the box.” We found this problem too late to be able to fix it before releases of the RTM product, but it’s pretty easy to fix.</p>  <p>MVP Jonathan Kehayias has posted the <a href="http://sqlskills.com/blogs/jonathan/post/Workaround-for-Bug-in-Activity-Tracking-Event-Session-Template-in-2012-RC0.aspx">steps to fix</a> this problem along with a corrected copy of the Activity Tracking template – check it out.</p>  <p>   <p>We are hoping to fix this in the first service pack of SQL Server 2012.</p>    <p>- Mike</p></p>]]></content:encoded>
    </item>
    <item>
      <title>Introducing the Extended Events Reader</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/introducing-the-extended-events-reader</link>
      <pubDate>Wed, 20 Jul 2011 14:14:00 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2011/07/20/introducing-the-extended-events-reader/</guid>
      <description><![CDATA[Check out What's new for Extended Events in SQL Server Codenamed &quot;Denali&quot; CTP3 for an...]]></description>
      <content:encoded><![CDATA[<p>Check out <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/13/what-s-new-for-extended-events-in-sql-server-codenamed-denali-ctp3.aspx">What's new for Extended Events in SQL Server Codenamed &quot;Denali&quot; CTP3</a> for an overview of all of the new functionality released in CTP3. This post covers the details of the “reader” API, which we call the XeReader, that you can use to programmatically access both XEL files and the near-live event stream from a running session. You can find information about the Extended Events object model in my earlier post: <a href="http://blogs.msdn.com/b/extended_events/archive/2011/01/20/introducing-the-extended-events-object-model.aspx">Introducing the Extended Events Object Model</a>.</p>  <h4><a name="_Toc286048385"></a>Event stream defined</h4>  <p>An event stream is pretty much what it sounds like, a stream of events that comes out of a running session. You will not find an option to configure the event stream in the UI or Extended Events DDL, it is accessed using the API described in this post. All the session configuration is handled under the covers. There are a few things to understand about the event stream before I dive into some examples:</p>  <ul>   <li>The event stream is asynchronous, not live, but to make the experience seem “more live” the event stream modifies the latency behavior of the source event session. When the event stream is hooked to an event session, the latency period specified by MAX_DISPATCH_LATENCY is changed to 3 seconds. When the event stream is disconnected, the latency is changed back to it’s original value. You may notice some odd behavior if you connect more than one XeReader to the same event session; the latency modification assumes only one connection so the <span style="text-decoration: underline">first disconnect</span> from the event session will revert the latency back to the original value (eg. no ref-counting). </li>    <li>The event stream aggressively follows the <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/13/what-s-new-for-extended-events-in-sql-server-codenamed-denali-ctp3.aspx">prime directive</a> – if the application utilizing the event stream API gets far enough behind in processing events that it risks blocking the server, the application will be disconnected. This is to prevent a “client tracing” application from bringing down a server; a problem often documented with SQL Profiler. If the event rate from your event session is so high that it causes a disconnection, then the event file is a more appropriate target for you. </li> </ul>  <h4><a name="_Toc286048386"></a>Exploring the API</h4>  <p>From the point of view of the XeReader, there is no difference between an XEL file and an event stream aside from the mechanism used to obtain the data. The main object in the XeReader is the QueriableXEventData object, which returns an enumerable list of events.</p>  <h5>Using the XeReader API</h5>  <p>In order to code against the API you’ll need to add a reference to the following assembly:</p>  <p><em>Microsoft.SqlServer.XEvent.Linq.dll</em></p>  <p>You’ll also need to add the following namespaces to your classes.</p>  <p><em>using Microsoft.SqlServer.XEvent.Linq;</em></p>  <p>Note: By the time we release “Denali” you will also need to add a second namespace, <em>Microsoft.SqlServer.Xevent</em>, to your code. Just letting you know so it’s not a surprise.</p>  <h5>Reading an event file (XEL)</h5>  <p>The XeReader supports reading the legacy XEL/XEM from SQL Server 2008 &amp; SQL Server 2008 R2 as well as the XEL file produced in SQL Server “Denali” CTP2 and above. There is no support for reading the files created in SQL Server “Denali” CTP1. There are three versions of the constructor that accept files:</p>  <ul>   <li>A single string with a valid path. </li>    <li>A single string array containing a set of paths to XEL files. </li>    <li>Two string arrays containing sets of paths to XEL and XEM files respectively. </li> </ul>  <p>The paths can be fully qualified files or any valid representation of a path using wildcards. Here are a couple examples:</p>  <p><span style="text-decoration: underline">Read all XEL files from a specific location</span><span style="text-decoration: underline"></span></p>  <pre class="csharpcode">QueryableXEventData events = <span class="kwrd">new</span> QueryableXEventData(<span class="str">@&quot;C:\Temp\myFile*.xel&quot;</span>);</pre>

<p><span style="text-decoration: underline">Read a specified multiple of XEL files</span></p>

<pre class="csharpcode"><span class="kwrd">string</span>[] fileList = <span class="kwrd">new</span> <span class="kwrd">string</span>[2];
fileList[0] = <span class="str">@&quot;C:\Temp\demo_trace_0_129418467298110000.xel&quot;</span>;
fileList[1] = <span class="str">@&quot;C:\Temp\demo_trace_0_129391767647570000.xel&quot;</span>;

QueryableXEventData events = <span class="kwrd">new</span> QueryableXEventData(fileList);</pre>

<p><span style="text-decoration: underline">Provide both XEL and XEM files</span></p>

<pre class="csharpcode"><span class="kwrd">string</span>[] xelFiles = <span class="kwrd">new</span> <span class="kwrd">string</span>[1];
xelFiles[0] = <span class="str">@&quot;C:\Temp\demo_trace_0_129418467298110000.xel&quot;</span>;
<span class="kwrd">string</span>[] xemFiles = <span class="kwrd">new</span> <span class="kwrd">string</span>[1];
xemFiles[1] = <span class="str">@&quot;C:\Temp\demo_trace_0_129418467298110000.xem&quot;</span>;

QueryableXEventData events = <span class="kwrd">new</span> QueryableXEventData(xelFiles, xemFiles);</pre>

<p>You get the idea.</p>

<h5>Reading an event stream</h5>

<p>You can read a stream from a running session by providing a connection string and event session name to the constructor along with a couple extra options.</p>

<pre class="csharpcode">QueryableXEventData stream = <span class="kwrd">new</span> QueryableXEventData(
    <span class="str">@&quot;Data Source = (local); Initial Catalog = master; Integrated Security = SSPI&quot;</span>, <br />    <span class="str">&quot;alert_me&quot;</span>, 
    EventStreamSourceOptions.EventStream, 
    EventStreamCacheOptions.DoNotCache);</pre>

<ul>
  <li>EventStreamSourceOptions – EventStream is the only option that exists at this point. We’ll be adding one more option before we release but I’ll leave that for a later blog post when it’s relevant. </li>

  <li>EventStreamCacheOptions – You can either choose to not cache any data (DoNotCache) or to cache the data (CacheToDisk). This option determines whether you can enumerate across the history of events that have come from the stream. The DoNotCache option will pull events from the server as fast as possible and keep them in memory as long as possible. It is possible for events to be ejected from memory before they are processed by the enumerator. The CacheToDisk option will store events to the disk until the disk is full. </li>
</ul>

<h5>Working with the Events</h5>

<p>The constructors all return an enumerable collection of type PublishedEvent, so the code to work with the events is identical regardless of source. I’ll cover the basics here to get you started.</p>

<p>You can loop through the collection of events just like you would expect for an enumerable object so you can imagine using a <i>foreach</i> to process each event. Additionally, each PublishedEvent object, contains collections for Fields and Actions that return the PublishedEventField and PublishedAction objects respectively. Taken together it’s a straight forward operation to list out all the events along with their fields and actions using code similar to this:</p>

<pre class="csharpcode"><span class="kwrd">foreach</span> (PublishedEvent evt <span class="kwrd">in</span> events)
{
      Console.WriteLine(evt.Name);

      <span class="kwrd">foreach</span> (PublishedEventField fld <span class="kwrd">in</span> evt.Fields)
        {
            Console.WriteLine(<span class="str">&quot;\tField: {0} = {1}&quot;</span>, fld.Name, fld.Value);
        }

      <span class="kwrd">foreach</span> (PublishedAction act <span class="kwrd">in</span> evt.Actions)
        {
            Console.WriteLine(<span class="str">&quot;\tAction: {0} = {1}&quot;</span>, act.Name, act.Value);
        } 
}</pre>

<p>You can perform conditional expressions as you would expect, say if you wanted to perform an action based on a specific value being returned from a field:</p>

<pre class="csharpcode"><span class="kwrd">if</span> (evt.Fields[<span class="str">&quot;field_name&quot;</span>].Value == <span class="str">&quot;foo&quot;</span>)</pre>

<blockquote>
  <p>or</p>
</blockquote>

<pre class="csharpcode"><span class="kwrd">if</span> (fld.Value == <span class="str">&quot;foo&quot;</span>)</pre>

<p>It is worth pointing out some “weirdness” associated with map fields if you want to evaluate using the friendly text that you would find in dm_xe_map_values rather than the integer map_key. You have to explicitly cast the field to a MapValue:</p>

<pre class="csharpcode"><span class="kwrd">if</span> (((MapValue)evt.Fields[<span class="str">&quot;field_name&quot;</span>].Value).Value == <span class="str">&quot;foo&quot;</span> )</pre>

<p>Again, you get the idea. This is really the core of the XeReader and the part I expect you’ll be working with the most. To make your life a little easier, I’ve attached a files that contains all this code in a runnable format, just add a reference to the assembly and you should be ready to start experimenting.</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:c66c510c-fc4f-4482-a0ce-5d8857acd3d7" class="wlWriterEditableSmartContent"><p>Download the Extended Event Reader <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/13212E00Program_413A0BD62E00cs" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/1321_2E00_Program_5F00_413A0BD6_2E00_cs" target="_blank">sample code</a></p></div>

<p>Happy Eventing</p>

<p>- Mike</p>]]></content:encoded>
    </item>
    <item>
      <title>Introducing the Extended Events User Interface</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/introducing-the-extended-events-user-interface</link>
      <pubDate>Wed, 13 Jul 2011 08:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2011/07/13/introducing-the-extended-events-user-interface/</guid>
      <description><![CDATA[Check out What's new for Extended Events in SQL Server Codenamed "Denali" CTP3 for an overview of...]]></description>
      <content:encoded><![CDATA[<p>Check out <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/13/what-s-new-for-extended-events-in-sql-server-codenamed-denali-ctp3.aspx">What's new for Extended Events in SQL Server Codenamed "Denali" CTP3</a> for an overview of all of the new functionality released in CTP3. This post details the new user interface. In my overview post I mentioned that the user interface is built directly into management studio (SSMS) and that there are four parts:</p>
<ol>
<li>The session list in Object Explorer.</li>
<li>A Create Session wizard.</li>
<li>A Create Session dialog.</li>
<li>A display grid.</li>
</ol>
<p>This post focuses on the mechanisms for creating event sessions and displaying event session data.</p>
<h4><a name="_Toc286048381"></a>Creating and modifying event sessions</h4>
<p>The New Session Wizard and dialog share many common UI elements, so I&rsquo;ll just cover the dialog. If a notable difference exists for the wizard, I&rsquo;ll call it out at the appropriate place. A picture is worth a thousand words, so here is the pictorial tour of the new user interface.</p>
<h5>General page</h5>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/3757.clip_image002_3E2BD39E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/3757.clip_5F00_image002_5F00_3E2BD39E.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/6404.clip_image002_thumb_4F9C3476.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/6404.clip_5F00_image002_5F00_thumb_5F00_4F9C3476.png" width="554" height="428" /></a></p>
<p>The <b>General</b> page collects the basic information about the session:</p>
<p>&middot; Name &ndash; You can figure this one out.</p>
<p>&middot; Template &ndash; We&rsquo;ve carried over the idea of templates similar to SQL Profiler. You can export any session you&rsquo;ve created to a template (Expand the context menu of your event session and click <b>Export Session&hellip;</b>). If you save the template to the default location, it will show up in this dropdown under the <i>User Templates</i> category.</p>
<p>&middot; Schedule &ndash; You can choose to make this an Autostart event session, start the session immediately after you complete the dialog and even choose to start up the event stream viewer. (More on that later.)</p>
<p>&middot; Causality Tracking &ndash; Turn on the correlation ids in your trace.</p>
<p><strong>Wizard differences: </strong>These options are spread across three different wizard steps.</p>
<h5>Event page - Library</h5>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5822.clip_image005_766A4AB6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/5822.clip_5F00_image005_5F00_766A4AB6.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image005" border="0" alt="clip_image005" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/7558.clip_image005_thumb_3634313C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/7558.clip_5F00_image005_5F00_thumb_5F00_3634313C.png" width="434" height="362" /></a></p>
<p>The Event page has a couple parts. The Event Library allows you to select which events you want to add to your event session. The library supports Excel-like filtering using dropdown lists for Category and Channel. You can also search for specific events by just typing in the search text box. You choose an event by double-clicking or by selecting it and clicking the <b>right arrow</b> to move it to the <b>Selected events</b> list. We support Shift+Click and Ctrl+Click for choosing multiple events at once.</p>
<h5>Event page &ndash; Configure</h5>
<p>In Extended Events, each event can be extended to include additional data or cause a specific action, only fire under defined conditions and to enable optional fields. Clicking on the <b>Configure</b> button takes you to the advanced event configuration options. You configure an event by selecting it in the <b>Selected events</b> list and then setting the configuration options on one of the tabs. When you select multiple events, the configuration options will apply to all selected events.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5305.clip_image007_5D02477C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/5305.clip_5F00_image007_5F00_5D02477C.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image007" border="0" alt="clip_image007" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/7484.clip_image007_thumb_20D67BD4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/7484.clip_5F00_image007_5F00_thumb_5F00_20D67BD4.png" width="434" height="364" /></a></p>
<p>The <b>Global Fields (Actions)</b> tab allows you select the list of Actions that you want to append to the event(s).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/0121.clip_image009_7591E4CC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/0121.clip_5F00_image009_5F00_7591E4CC.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image009" border="0" alt="clip_image009" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5315.clip_image009_thumb_6E72A854.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/5315.clip_5F00_image009_5F00_thumb_5F00_6E72A854.png" width="434" height="105" /></a></p>
<p>The <b>Filter (Predicate)</b> tab is used to define the conditions under which the event will be collected.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/7043.clip_image011_67536BDC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/7043.clip_5F00_image011_5F00_67536BDC.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image011" border="0" alt="clip_image011" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/1780.clip_image011_thumb_3C0ED4D5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/1780.clip_5F00_image011_5F00_thumb_5F00_3C0ED4D5.png" width="434" height="282" /></a></p>
<p>The <b>Event Fields</b> table allows you to enable or disable the collection of optional fields. (Fields without a checkbox are always collected.) You can also see the description and data type of each field on this tab.</p>
<p><strong>Wizard differences:</strong> Global Fields and Predicates apply to all selected events. You cannot configure the events individually.</p>
<h5>Data Storage page</h5>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5305.clip_image014_3FACEFB2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/5305.clip_5F00_image014_5F00_3FACEFB2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image014" border="0" alt="clip_image014" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/7484.clip_image014_thumb_146858AB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/7484.clip_5F00_image014_5F00_thumb_5F00_146858AB.png" width="554" height="465" /></a></p>
<p>You determine how the event session data is stored on this page by specifying the target for the session. You can specify more than one target for any session, but you can only use each target once. Each target will present a set of configuration options on the bottom of the page.</p>
<p><strong>Wizard differences:</strong> The wizard supports only the event file and ring buffer targets.</p>
<h5>Advanced page</h5>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/2678.clip_image017_3B366EEB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/2678.clip_5F00_image017_5F00_3B366EEB.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image017" border="0" alt="clip_image017" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/7077.clip_image017_thumb_34173273.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/7077.clip_5F00_image017_5F00_thumb_5F00_34173273.png" width="554" height="327" /></a></p>
<p>Configure the options for the entire event session here. We use the same defaults you would get with the DDL syntax.</p>
<p><strong>Wizard differences: </strong>You cannot configure the event session options in the wizard, the defaults are used.</p>
<h5>Other stuff</h5>
<p>You may have noticed from the screen shots that you can script out your configured event session from the user interface using the button at the top of the page. The button becomes enabled as soon as you have enough of the event session configured such that the DDL would execute without error.</p>
<p>You can change the configuration of an event session by right-clicking the session name in Object Explorer and clicking <b>Properties</b>. The same user interface will be presented showing all your configured settings. Most settings can be changed on a running session, but you&rsquo;ll need to stop the session to change the Advanced options. You cannot change the target configuration (<b>Data Storage </b>page) on an existing target, you&rsquo;ll need to delete the target and re-add it to change that. You will also find that the <b>Script </b>button is not enabled in the Properties dialog, you can still script your event session to DDL, but you&rsquo;ll need to do it from Object Explorer by right-clicking the session name and choosing one of the <b>Script Session as&hellip;</b> commands.</p>
<p><strong>Wizard differences: </strong>The wizard is not re-entrant. Sessions created in the wizard can be modified using the Property dialog just like any other session.</p>
<h4><a name="_Toc286048382"></a>Viewing event session data</h4>
<p>SSMS includes an event session data viewer for all of the supported targets with the exception of the ETW file target. (There are many other tools for working with ETL files.) There are basically two different types of event session data display.</p>
<h5>In-memory targets</h5>
<p>The in-memory targets include: ring buffer, event counter, histogram and event pairing. The data from these targets is displayed in a simple grid format.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5824.clip_image020_7F0AA342.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/5824.clip_5F00_image020_5F00_7F0AA342.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image020" border="0" alt="clip_image020" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/0118.clip_image020_thumb_5EEF9685.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/0118.clip_5F00_image020_5F00_thumb_5F00_5EEF9685.png" width="504" height="135" /></a></p>
<p>By default you see a &ldquo;point in time&rdquo; view of the data when you opened the display. You can either manually refresh the data or have it refresh on a schedule from the context menu. The ring buffer is a bit special in that the display shows you a single row containing the XML output of the ring buffer. You can double-click the row to open an XML document, but there is no event by event grid view for the ring buffer, sorry.</p>
<h5>Event stream and event file</h5>
<p>You can open a &ldquo;live view&rdquo; of a running session by right-clicking on the session name and choosing the <b>Watch Live Data</b> menu item. This will open a page in SSMS that provides you with a scrolling display of the events as they come from the event session. This is similar to the behavior that exists in SQL Profiler with the major difference being that Extended Events does not cause the performance degradation that you might be used to with SQL Profiler. Extended Events will never block the server waiting for the client event stream view; we&rsquo;re so serious about this that the event stream is disconnected if the client becomes too slow that it will block the server workload. (Remember the <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/13/what-s-new-for-extended-events-in-sql-server-codenamed-denali-ctp3.aspx">prime directive</a> &ndash; this is one of those tradeoffs.) If you have a very busy server (eg. lots of events) the file target will be a more appropriate target.</p>
<p>The event file target uses the XEL extension by default, and that extension is associated with SSMS so that you can open an event file by double-clicking or simply dragging it onto the SSMS window. You can also open event files in two different ways from the File menu:</p>
<p><b>File | Open | File</b> &ndash; Pick an XEL file and click <b>Open</b></p>
<p><b>File | Open | Merge Extended Event files</b> &ndash; Use the dialog to collect multiple files to be merged</p>
<p>Both the event steam and event files are displayed in the same user interface:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/1207.clip_image022_1AAF2F39.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/1207.clip_5F00_image022_5F00_1AAF2F39.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image022" border="0" alt="clip_image022" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/0624.clip_image022_thumb_2C8BC306.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/0624.clip_5F00_image022_5F00_thumb_5F00_2C8BC306.png" width="704" height="535" /></a></p>
<p>The picture is a bit small, but you get the idea. Open up an XEL file in SSMS to get the full experience.</p>
<p>The first thing you won&rsquo;t notice, but now you will because I&rsquo;m telling you, is that there is a custom toolbar for Extended Events; there is also a menu added. You can control all the functionality of the display UI using these. The first thing you will notice is that the default view has only two columns, name and timestamp, all the other columns for an event are shown in the <b>Details</b> pane when you select a specific row in the grid. There is a bunch of functionality in this UI, almost too much to fit into a summary such as this, so I&rsquo;ll hit the high points and let you explore.</p>
<p>&middot; You can add additional columns to the grid by either right-clicking the in the <b>Details</b> pane and choosing <b>Show Column in Table</b> or by clicking the <b>Choose Columns</b> button to open the Choose Columns dialog.</p>
<p>&middot; You can <b>Find</b> event records using the typical SSMS find behavior.</p>
<p>&middot; You can <b>Bookmark</b> records of interest and move between bookmarked records.</p>
<p>&middot; You can apply a filter to the results using a flexible criteria builder. (This is worth a picture; so much better than SQL Profiler!)</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/3362.clip_image024_333ECC89.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/3362.clip_5F00_image024_5F00_333ECC89.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image024" border="0" alt="clip_image024" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/0537.clip_image024_thumb_1323BFCC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/0537.clip_5F00_image024_5F00_thumb_5F00_1323BFCC.png" width="504" height="312" /></a></p>
<p>&middot; You can use the <b>Grouping</b> and <b>Aggregation </b>commands to do some basic analysis of your data directly in the display UI.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/3264.clip_image026_0C048354.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/3264.clip_5F00_image026_5F00_0C048354.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="clip_image026" border="0" alt="clip_image026" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5811.clip_image026_thumb_1DE11721.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-35-19-metablogapi/5811.clip_5F00_image026_5F00_thumb_5F00_1DE11721.png" width="454" height="304" /></a></p>
<p>&middot; You can save the configuration of the display table (columns, filter, sorting and group/aggregation) using the <b>View Settings </b>button. (Note: This button name may change before RTM.)</p>
<p>&middot; You can export the list of events to a SQL Server table, CSV or XEL using the <b>Export to</b> menu item. (Note: This is only on the menu, not the command bar.)</p>
<p>&middot; You can Start and Stop the collection of the data and control the scrolling of the data in the window for the event stream.</p>
<p>That about wraps up the pictorial tour of the new Extended Events user interface. Take it out for a spin and let us know what you think. If you find any problems, or have suggestions for future versions, please post them to Microsoft Connect.&nbsp; If you have questions, post them to the <a href="http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/threads">SQL Server Database Engine</a> forum.</p>
<p>Happy Eventing!</p>
<p>- Mike</p>]]></content:encoded>
    </item>
    <item>
      <title>What’s New for Extended Events in SQL Server Codenamed “Denali” CTP3</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/whats-new-for-extended-events-in-sql-server-codenamed-denali-ctp3</link>
      <pubDate>Wed, 13 Jul 2011 08:25:00 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2011/07/13/whats-new-for-extended-events-in-sql-server-codenamed-denali-ctp3/</guid>
      <description><![CDATA[CTP3 is finally here and the crowd goes wild! Since I&rsquo;m sure everyone has been anticipating...]]></description>
      <content:encoded><![CDATA[<p><a href="https://www.microsoft.com/sqlserver/">CTP3</a> is finally here and the crowd goes wild! Since I&rsquo;m sure everyone has been anticipating the CTP3 updates to Extended Events (because, let&rsquo;s face it, Extended Events is the most important part of the product, right?) let&rsquo;s get to it.</p>
<h1>Introduction</h1>
<p>I&rsquo;m going to cover the new features at a high level in this post and then drill into a couple specific features in more detail in posts dedicated to that topic. Before I get into the &ldquo;meat&rdquo; of this post I wanted to spend a few sentence writing about the design philosophy we&rsquo;ve followed as we&rsquo;ve created Extended Events. Every feature gets to a point where a trade-off has to be made and the design philosophy guides us in making those trade-offs.</p>
<p>Foremost is our prime directive (not that I&rsquo;m a Star Trek&trade; fan):</p>
<p><b>The most important workload on the server is the customer workload; diagnostic systems should not prevent the customer workload from running.</b></p>
<p>This doesn&rsquo;t mean that a diagnostic workload won&rsquo;t impact server performance, it will. It means that in cases where we have to make a choice between the activity of the customer workload and the diagnostic workload, the customer workload wins, period. This has been the prime directive of the Extended Events team since the beginning and it didn&rsquo;t change in &ldquo;Denali.&rdquo;</p>
<p>The goal for &ldquo;Denali&rdquo; has been twofold:</p>
<ol>
<li>Provide a diagnostic tracing facility, built on Extended Events, that will not just replace the existing SQL Trace/SQL Profiler based system, but exceed it.</li>
<li>Drastically improve the usability of Extended Events.</li>
</ol>
<p>A significant part of meeting our first goal was accomplished in CTP1 by providing data parity with SQL Trace event classes. I&rsquo;ve already discussed <a href="http://blogs.msdn.com/b/extended_events/archive/2010/12/10/migrating-from-sql-trace-to-extended-events.aspx">migration from SQL Trace to Extended Events</a> in the blog, so I won&rsquo;t go into details about that work here. With that preamble, let&rsquo;s take a look and how we accomplished the second goal.</p>
<h1>Extended Events User Interface</h1>
<p><em><span style="font-size: small;" size="3">Get more details: <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/13/introducing-the-extended-events-user-interface.aspx">Introducing the Extended Events User Interface</a></span></em></p>
<p>This won&rsquo;t be a surprise to many of you, but we&rsquo;ve created a user interface for Extended Events and you&rsquo;ll find it in CTP3. Having a user interface was the most common user request, by far, and we listened. SQL Profiler is too important to not have equivalent functionality. Making it much easier to configure and read event sessions is the primary way we delivered on our usability goal. The Extended Events user interface is built directly into SSMS and there are four primary pieces:</p>
<ul>
<li>Session list &ndash; You will find a list of sessions within the Object Explorer under the node <b>Management | Extended Events | Sessions</b>.</li>
<li>New Session Wizard &ndash; A wizard (duh) that provides a simplified experience for creating an event session. Only the most common options and functionality is exposed with everything else being configured automatically. Expand the context menu of the <b>Sessions</b> node and click <b>New Session Wizard</b>.</li>
<li>New Session dialog &ndash; The complete set of Extended Events configuration in handy dialog format. Expand the context menu of the <b>Sessions </b>node and click <b>New Session&hellip;</b>. The same dialog is used for creating new sessions and for modifying existing sessions (click <b>Properties</b> on the context menu).</li>
<li>Extended Events display &ndash; A collection of SSMS pages (tabs like the Query window) that display Extended Events trace data.</li>
</ul>
<h3>The user interface you designed&hellip;really</h3>
<p>We didn&rsquo;t just listen to the feedback that we needed a user interface, we also listened to the feedback we got throughout the design and development process. This UI represents more than just the work of the Microsoft development team, but also the feedback of many SQL Server MVPs, usability study participants and anyone who would talk to us at the various conferences where we presented the UI. We took something useful away from every customer interaction and made significant changes based on that feedback. Thanks to everyone who took the time to provide your feedback. (And keep it coming &ndash; as you explore CTP3 send us your feedback using Microsoft Connect.)</p>
<h3>You might want to sit down for this next section</h3>
<p>It&rsquo;s an unpopular word, but I have to say it &hellip; Deprecation.</p>
<p>Yeah, I said it; we are announcing deprecation of SQL Trace in Denali. Before everyone goes off the deep end, remember, this is only the <span style="text-decoration: underline;">announce</span> phase which means that nothing actually changes in Denali, we&rsquo;re just letting you know that we&rsquo;re phasing it out in favor of the new system over the next few releases so now is a good time to start investigating how to migrate. (See the link in the Introduction for more details.)</p>
<h1>Programming Extended Events</h1>
<p><em><span style="font-size: small;" size="3">Get more details: <a href="http://blogs.msdn.com/b/extended_events/archive/2011/07/20/introducing-the-extended-events-reader.aspx">Introducing the Extended Events Reader</a></span></em></p>
<p>Another important aspect of creating a usable diagnostic system is a programmatic interface. (Not everyone loves DDL as much as we do apparently.) We&rsquo;ve covered this in two pieces:</p>
<ul>
<li>A &ldquo;management&rdquo; API that lets you create and modify event sessions as well as explore the Extended Events metadata on a server. This API was release in CTP1 and I&rsquo;ve already provided examples in my post <a href="http://blogs.msdn.com/b/extended_events/archive/2011/01/20/introducing-the-extended-events-object-model.aspx">Introducing the Extended Events Object Model</a>.</li>
<li>A &ldquo;reader&rdquo; API that provides functionality for reading event files (XEL) and event streams coming from a running event session.</li>
</ul>
<p>The UI is built on top of these APIs so you have all the capabilities you need to write your own customized tools for working with Extended Events.</p>
<h1></h1>
<h1>The &ldquo;other&rdquo; stuff</h1>
<p>There are always a host of little things that we add, change or fix when we&rsquo;re improving a feature. I don&rsquo;t want to deprive anyone of the &ldquo;Joy of Discovery&rdquo; that comes with finding these little bits and pieces, so stop reading now if you want to hunt them down on your own. For the rest of you, here is the list of bits and pieces that we hope will make the Extended Events world a little better for you.</p>
<h3>Some (target) names have been changed to protect the innocent</h3>
<p>We&rsquo;ve changed the names of some of the targets to be friendlier:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="319">
<p><b>Old Target Name</b></p>
</td>
<td valign="top" width="319">
<p><b>New Target Name</b></p>
</td>
</tr>
<tr>
<td valign="top" width="319">
<p>asynchronous_file_target</p>
</td>
<td valign="top" width="319">
<p>event_file</p>
</td>
</tr>
<tr>
<td valign="top" width="319">
<p>synchronous_event_counter</p>
</td>
<td valign="top" width="319">
<p>event_counter</p>
</td>
</tr>
<tr>
<td valign="top" width="319">
<p>asynchronous_bucketizer</p>
</td>
<td valign="top" width="319">
<p>histogram</p>
</td>
</tr>
<tr>
<td valign="top" width="319">
<p>synchronous_bucketizer</p>
</td>
<td valign="top" width="319">
<p>histogram (I&rsquo;ll explain below)</p>
</td>
</tr>
</tbody>
</table>
<p>To make this change easier we&rsquo;ve done some work under the covers:</p>
<ul>
<li>ADD TARGET with the old target names will <span style="text-decoration: underline;">still work</span>. We do name fixup inside SQL Server when we execute the DDL.</li>
<li>DROP TARGET with the old target names <span style="text-decoration: underline;">will not work</span>. We fixed up the names so there are no records in the catalog with the old names.</li>
<li>The target_name field of dm_xe_session_targets will be fixed up to have the new target names for any running sessions during Upgrade.</li>
<li>The name field of server_event_session_targets will be fixed up to have the new target names for any configured session during Upgrade.</li>
</ul>
<p>Note on histogram target &ndash; There is not strong evidence to support that people are using both the synchronous and asynchronous bucketizer together in a single session so we used the renaming event to also eliminate this duplication. We have a single histogram target now that is asynchronous.</p>
<h3>There can be only one &ndash; file that is</h3>
<p>We&rsquo;ve eliminated the metadata file all together. That&rsquo;s right, no more XEM file, it just didn&rsquo;t make sense and it&rsquo;s kind of a pain to have to worry about dragging the extra file around if you&rsquo;re sending logs to other folks. Both the server reader function, fn_xe_file_target_read_file and the new Reader API are fully backwards compatible with the SQL Server 2008 and SQL Server 2008 R2 &ldquo;dual file&rdquo; format.</p>
<p><strong>Note:</strong> We do not support the XEL/XEM files created in SQL Server Codenamed &ldquo;Denali&rdquo; CTP1.</p>
<p>The single file model has some downstream implications for event_file target and the fn_xe_file_target_read_file function.</p>
<p><b>event_file</b> &ndash; You no longer need to set the <i>metadatafile</i> attribute but it is still available (but optional) so as not to break your DDL scripts. If you do provide a value for <i>metadatafile</i> it will be ignored for valid paths and it will throw an error for invalid paths.</p>
<p><b>fn_xe_file_target_read_file</b> &ndash; The <i>mdpath</i> attribute is optional and ignored (but will throw if you provide an invalid path) when the <i>filename</i> path represents &ldquo;Denali&rdquo; XEL version files. You should just pass &lsquo;NULL&rsquo; for <i>mdpath</i> as you would for all other optional attributes.</p>
<h3></h3>
<h3>New options available for some targets</h3>
<p>We&rsquo;ve added a few new options to make some of the targets a bit more flexible.</p>
<p><b>pair_matching</b> &ndash; In order to help prevent the pair_matching target from running amok in cases where you have an excessive number of orphaned records we&rsquo;ve added the <i>max_orphans</i> option to the target with a default of 10000. As you might surmise, this option controls the number of orphaned records that will be maintained in the pair_matching target.</p>
<p><b>ring_buffer</b> &ndash; We&rsquo;ve introduce the <i>max_events_limit</i> for the ring_buffer to provide a deterministic way to control the number of events in the target. The default value is 1000 and we&rsquo;ve changed the default for <i>max_memory</i> to be unlimited, meaning that the ring_buffer will use as much memory as required to store 1000 events by default. You can set one or both of these. When both are set we&rsquo;ll honor the one that is hit first.</p>
<h1>Wrapping up</h1>
<p>Now that you have the overview go ahead and take Extended Events out for a spin. Dig into the detailed posts for more information about the UI and the programmatic APIs. If you find any issues or have suggestions for future advancements please post an item into Microsoft Connect so that others can vote on it. If you have questions, post them to the <a href="http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/threads">SQL Server Database Engine</a> forum.</p>
<p>Happy Eventing!</p>
<p>- Mike</p>]]></content:encoded>
    </item>
    <item>
      <title>Sampling SQL server batch activity</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/sampling-sql-server-batch-activity</link>
      <pubDate>Thu, 10 Feb 2011 17:25:00 GMT</pubDate>
      <dc:creator><![CDATA[Jerome Halmans]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2011/02/10/sampling-sql-server-batch-activity/</guid>
      <description><![CDATA[Recently I was troubleshooting a performance issue on an internal tracking workload and needed to...]]></description>
      <content:encoded><![CDATA[<p class="MsoNormal"><span style="font-size: small;"><span style="font-family: Calibri;">Recently I was troubleshooting a performance issue on an internal tracking workload and needed to collect some very low level events over a period of 3-4 hours.<span style="mso-spacerun: yes;">&nbsp; </span>During analysis of the data I found that a common pattern I was using was to find a batch with a duration that was longer than average and follow all the events it produced.<span style="mso-spacerun: yes;">&nbsp; </span></span></span></p>
<p class="MsoNormal">
<p><span style="font-family: Calibri;">
<p><span style="mso-spacerun: yes;">
<p class="MsoNormal"><span style="font-size: small;">This pattern got me thinking that I was discarding a substantial amount of event data that had been collected, and that it would be great to be able to reduce the collection overhead on the server if I could still get all activity from some batches.</span></p>
<p class="MsoNormal"><span style="font-size: small;">In the past I&rsquo;ve used a sampling technique based on the counter predicate to build a baseline of overall activity (see Mikes post </span><a href="http://blogs.msdn.com/b/extended_events/archive/2010/05/14/try-a-sample-using-the-counter-predicate-for-event-sampling.aspx"><span style="color: #0000ff; font-size: small;">here</span></a><span style="font-size: small;">).<span style="mso-spacerun: yes;">&nbsp; </span>This isn&rsquo;t exactly what I want though as there would certainly be events from a particular batch that wouldn&rsquo;t pass the predicate.<span style="mso-spacerun: yes;">&nbsp; </span>What I need is a way to identify streams of work and select say one in ten of them to watch, and sql server provides just such a mechanism: session_id.<span style="mso-spacerun: yes;">&nbsp; </span>Session_id is a server assigned integer that is bound to a connection at login and lasts until logout.<span style="mso-spacerun: yes;">&nbsp; </span>So by combining the session_id predicate source and the divides_by_uint64 predicate comparator we can limit collection, and still get all the events in batches for investigation.</span></p>
</span></p>
<span style="font-size: small;">
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">CREATE</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">EVENT</span> <span style="color: blue;">SESSION</span> <span style="color: teal;">session_10_percent</span> <span style="color: blue;">ON</span> <span style="color: blue;">SERVER</span> <o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">ADD</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">EVENT</span> <span style="color: teal;">sqlserver</span><span style="color: gray;">.</span><span style="color: teal;">sql_statement_starting</span><span style="color: gray;">(</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">WHERE </span><span style="color: gray;">(</span><span style="color: teal;">package0</span><span style="color: gray;">.</span><span style="color: teal;">divides_by_uint64</span><span style="color: gray;">(</span><span style="color: teal;">sqlserver</span><span style="color: gray;">.</span><span style="color: teal;">session_id</span><span style="color: gray;">,</span>10<span style="color: gray;">))),</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">ADD</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">EVENT</span> <span style="color: teal;">sqlos</span><span style="color: gray;">.</span><span style="color: teal;">wait_info</span><span style="color: blue;"> </span><span style="color: gray;">(</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">WHERE </span><span style="color: gray;">(</span><span style="color: teal;">package0</span><span style="color: gray;">.</span><span style="color: teal;">divides_by_uint64</span><span style="color: gray;">(</span><span style="color: teal;">sqlserver</span><span style="color: gray;">.</span><span style="color: teal;">session_id</span><span style="color: gray;">,</span>10<span style="color: gray;">))),</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">ADD</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">EVENT</span> <span style="color: teal;">sqlos</span><span style="color: gray;">.</span><span style="color: teal;">wait_info_external</span><span style="color: blue;"> </span><span style="color: gray;">(</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">WHERE </span><span style="color: gray;">(</span><span style="color: teal;">package0</span><span style="color: gray;">.</span><span style="color: teal;">divides_by_uint64</span><span style="color: gray;">(</span><span style="color: teal;">sqlserver</span><span style="color: gray;">.</span><span style="color: teal;">session_id</span><span style="color: gray;">,</span>10<span style="color: gray;">))),</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">ADD</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">EVENT</span> <span style="color: teal;">sqlserver</span><span style="color: gray;">.</span><span style="color: teal;">sql_statement_completed</span><span style="color: gray;">(</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">WHERE </span><span style="color: gray;">(</span><span style="color: teal;">package0</span><span style="color: gray;">.</span><span style="color: teal;">divides_by_uint64</span><span style="color: gray;">(</span><span style="color: teal;">sqlserver</span><span style="color: gray;">.</span><span style="color: teal;">session_id</span><span style="color: gray;">,</span>10<span style="color: gray;">)))</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">ADD</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">TARGET</span> <span style="color: teal;">ring_buffer</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">WITH </span><span style="font-family: Consolas; color: gray; font-size: 9.5pt;">(</span><span style="font-family: Consolas; color: teal; font-size: 9.5pt;">MAX_DISPATCH_LATENCY</span><span style="font-family: Consolas; color: gray; font-size: 9.5pt;">=</span><span style="font-family: Consolas; font-size: 9.5pt;">30 <span style="color: teal;">SECONDS</span><span style="color: gray;">,</span><span style="color: teal;">TRACK_CAUSALITY</span><span style="color: gray;">=</span><span style="color: blue;">ON</span><span style="color: gray;">)</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">GO</span><span style="font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></p>
<p class="MsoNormal">&nbsp;</p>
</span></span><o:p><span style="font-family: Consolas; font-size: 9.5pt;"><o:p><span style="font-size: small;"><span style="font-family: Calibri;">There we go; event collection is reduced while still providing enough information to find the root of the problem.<span style="mso-spacerun: yes;">&nbsp; </span><o:p></o:p></span></span></o:p></span></o:p></p>
</p>
<p>
<p class="MsoNormal"><o:p><span style="font-family: Calibri; font-size: small;"></span></o:p></p>
<p class="MsoNormal"><span style="font-size: small;"><span style="font-family: Calibri;">By the way the performance issue turned out to be an IO issue, and the session definition above was more than enough to show long waits on PAGEIOLATCH*.<span style="font-family: Consolas; font-size: 9.5pt;"><o:p></o:p></span></span></span></p>
<p class="MsoNormal">&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</p>]]></content:encoded>
    </item>
    <item>
      <title>Introducing the Extended Events Object Model</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/introducing-the-extended-events-object-model</link>
      <pubDate>Wed, 19 Jan 2011 19:30:12 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2011/01/19/introducing-the-extended-events-object-model/</guid>
      <description><![CDATA[The primary focus we’ve had for Extended Events in SQL Server codenamed “Denali” is to offer a...]]></description>
      <content:encoded><![CDATA[<p>The primary focus we’ve had for Extended Events in SQL Server codenamed “Denali” is to offer a better user experience by providing options for working with the system beyond DDL. One of those options is the availability of a managed code object model. In this post I’ll describe the object model and it’s usage as well as provide sample code that shows how various objects are used.</p>  <p>In the graphic below you can see that there are two “sides” of the object model:</p>  <p><strong>Metadata</strong>: Describes the set of events, actions, targets, etc. that are available on the system. All access to the metadata objects has to go through the <strong>Package</strong> object.</p>  <p><strong>Runtime</strong>: Describes the event sessions that are configured and various aspects of their runtime state. All access to the runtime objects has to go through the <strong>Session</strong> object.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/5025.image_0456128B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-35-19-metablogapi/5025.image_5F00_0456128B.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/6102.image_thumb_579D32E4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-35-19-metablogapi/6102.image_5F00_thumb_5F00_579D32E4.png" width="514" height="608" /></a> </p>  <p>The top level object is named <strong>XEStore;</strong> you get to the XEStore by connecting to the program that uses Extended Events. At the current time the object model supports the SQL Server database engine, &lt;teaser&gt; but in the future there will likely be others.&lt;/teaser&gt; &lt;bummer&gt;(Sorry, I can’t discuss when or what at this point.)&lt;/bummer&gt; The object model is based on the SFC Framework which isn’t particularly important for most of the XE objects, but the XEStore is a type of SfcConnection so I thought it worth mentioning. Since we’re specifically after the XEStore in SQL Server, I’m using a SqlStoreConnection, which inherits SfcConnection, and I need to pass in a normal SqlConnection to get to my server.</p>  <pre class="code"><span style="color: blue">private static </span><span style="color: #2b91af">XEStore </span>ConnectToXEStore()
{
    Microsoft.SqlServer.Management.Sdk.Sfc.<span style="color: #2b91af">SqlStoreConnection </span>server;
    <span style="color: #2b91af">SqlConnectionStringBuilder </span>conBuild = <span style="color: blue">new </span><span style="color: #2b91af">SqlConnectionStringBuilder</span>();
    conBuild.DataSource = <span style="color: #a31515">&quot;(local)&quot;</span>;
    conBuild.InitialCatalog = <span style="color: #a31515">&quot;master&quot;</span>;
    conBuild.IntegratedSecurity = <span style="color: blue">true</span>;

    <span style="color: green">// Create the actual SqlStoreConnection...
    </span>server = <span style="color: blue">new </span>Microsoft.SqlServer.Management.Sdk.Sfc.<span style="color: #2b91af">SqlStoreConnection<br />                </span>(<span style="color: blue">new </span><span style="color: #2b91af">SqlConnection</span>(conBuild.ConnectionString.ToString()));

    <span style="color: green">// ...and then create the XEStore to return to the calling function.
    </span><span style="color: blue">return new </span><span style="color: #2b91af">XEStore</span>(server);
}</pre>

<p>In this case I’m using the SqlConnectonStringBuilder for clarity, but you can see how I could have just passed a connection string directly into the SqlStoreConnection constructor. The connection to the XEStore is the part that changes if I connect to a different program that uses Extended Events. Everything else will be identical.</p>

<p>In the interest of keeping this post short and helping you avoid a boat-load of Copy/Paste activities, I’ve just put all the sample code into a .cs file with comments throughout to help explain the various objects and tie them back to the Extended Event DMVs and Catalog that you’re already familiar with. I tested this code on the current, public CTP, so things should be working, but let me know if you run into any problems.</p>

<p>- Mike</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:1165aae7-7e2d-4660-afb4-b69bee1f2d6c" class="wlWriterEditableSmartContent"><p><div>Download sample code: <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/26202E00XeObjectModel_2943AD372E00cs" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-35-19-metablogapi/2620_2E00_XeObjectModel_5F00_2943AD37_2E00_cs" target="_blank">XeObjectModel.cs</a></div></p></div>]]></content:encoded>
    </item>
    <item>
      <title>Migrating from SQL Trace to Extended Events</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/migrating-from-sql-trace-to-extended-events</link>
      <pubDate>Fri, 10 Dec 2010 11:21:26 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2010/12/10/migrating-from-sql-trace-to-extended-events/</guid>
      <description><![CDATA[In SQL Server codenamed “Denali” we are moving our diagnostic tracing capabilities forward by...]]></description>
      <content:encoded><![CDATA[<p>In SQL Server codenamed “Denali” we are moving our diagnostic tracing capabilities forward by building a system on top of Extended Events. With every new system you face the specter of migration which is always a bit of a hassle. I’m obviously motivated to see everyone move their diagnostic tracing systems over to the new extended events based system, so I wanted to make sure we lowered the bar for the migration process to help ease your trials.</p>  <p>In my <a href="http://blogs.msdn.com/b/extended_events/archive/2010/11/18/what-s-new-for-extended-events-in-sql-server-code-named-denali-ctp1.aspx" target="_blank">initial post</a> on Denali CTP 1 I described a couple tables that we created that will help map the existing SQL Trace Event Classes to the equivalent Extended Events events. In this post I’ll describe the tables in a bit more details, explain the relationship between the SQL Trace objects (Event Class &amp; Column) and Extended Event objects (Events &amp; Actions) and at the end provide some sample code for a managed stored procedure that will take an existing SQL Trace session (eg. a trace that you can see in sys.Traces) and converts it into event session DDL.</p>  <h1></h1>  <h1>Can you relate?</h1>  <p>In some ways, SQL Trace and Extended Events is kind of like the Standard and Metric measuring systems in the United States. If you spend too much time trying to figure out how to convert between the two it will probably make your head hurt. It’s often better to just use the new system without trying to translate between the two. That said, people like to relate new things to the things they’re comfortable with, so, with some trepidation, I will now explain how these two systems are related to each other. First, some terms…</p>  <p>SQL Trace is made up of Event Classes and Columns. The Event Class occurs as the result of some activity in the database engine, for example, SQL:Batch Completed fires when a batch has completed executing on the server. Each Event Class can have any number of Columns associated with it and those Columns contain the data that is interesting about the Event Class, such as the duration or database name.</p>  <p>In Extended Events we have objects named Events, EventData field and Actions. The Event (some people call this an xEvent but I’ll stick with Event) is equivalent to the Event Class in SQL Trace since it is the thing that occurs as the result of some activity taking place in the server. An&#160; EventData field (from now on I’ll just refer to these as fields) is a piece of information that is highly correlated with the event and is always included as part of the schema of an Event. An Action is something that can be associated with any Event and it will cause some additional “action” to occur when ever the parent Event occurs. Actions can do a number of different things for example, there are Actions that collect additional data and, take memory dumps.</p>  <p>When mapping SQL Trace onto Extended Events, Columns are covered by a combination of both fields and Actions. Knowing exactly where a Column is covered by a field and where it is covered by an Action is a bit of an art, so we created the mapping tables to make you an Artist without the years of practice.</p>  <h1>Let me draw you a map.</h1>  <h2></h2>  <h2>Event Mapping</h2>  <p>The table dbo.trace_xe_event_map exists in the master database with the following structure:</p>  <table border="1" cellspacing="0" cellpadding="0"><tbody>     <tr>       <td valign="top" width="75">         <p><b>Column_name</b></p>       </td>        <td valign="top" width="47">         <p><b>Type</b></p>       </td>     </tr>      <tr>       <td valign="top" width="75">         <p>trace_event_id</p>       </td>        <td valign="top" width="47">         <p>smallint</p>       </td>     </tr>      <tr>       <td valign="top" width="75">         <p>package_name</p>       </td>        <td valign="top" width="47">         <p>nvarchar</p>       </td>     </tr>      <tr>       <td valign="top" width="75">         <p>xe_event_name</p>       </td>        <td valign="top" width="47">         <p>nvarchar</p>       </td>     </tr>   </tbody></table>  <p>By joining this table sys.trace_events using trace_event_id and to the sys.dm_xe_objects using xe_event_name you can get a fair amount of information about how Event Classes are related to Events. The most basic query this lends itself to is to match an Event Class with the corresponding Event.</p>  <blockquote>   <p><font color="#c0c0c0">SELECT        <br />&#160;&#160;&#160; t.trace_event_id,         <br />&#160;&#160;&#160; t.name [event_class],         <br />&#160;&#160;&#160; e.package_name,         <br />&#160;&#160;&#160; e.xe_event_name         <br />FROM sys.trace_events t INNER JOIN dbo.trace_xe_event_map e         <br />&#160;&#160;&#160; ON t.trace_event_id = e.trace_event_id</font></p> </blockquote>  <p>There are a couple things you’ll notice as you peruse the output of this query:</p>  <ul>   <li>For the most part, the names of Events are fairly close to the original Event Class; eg. SP:CacheMiss == sp_cache_miss, and so on. </li>    <li>We’ve mostly stuck to a one to one mapping between Event Classes and Events, but there are a few cases where we have combined when it made sense. For example, Data File Auto Grow, Log File Auto Grow, Data File Auto Shrink &amp; Log File Auto Shrink are now all covered by a single event named database_file_size_change. This just seemed like a “smarter” implementation for this type of event, you can get all the same information from this single event (grow/shrink, Data/Log, Auto/Manual growth) without having multiple different events. You can use Predicates if you want to limit the output to just one of the original Event Class measures. </li>    <li>There are some Event Classes that did not make the cut and were not migrated. These fall into two categories; there were a few Event Classes that had been deprecated, or that just did not make sense, so we didn’t migrate them. (You won’t find an Event related to mounting a tape – sorry.) The second class is bigger; with rare exception, we did not migrate any of the Event Classes that were related to Security Auditing using SQL Trace. We introduced the SQL Audit feature in SQL Server 2008 and that will be the compliance and auditing feature going forward. Doing this is a very deliberate decision to support separation of duties for DBAs. There are separate permissions required for SQL Audit and Extended Events tracing so you can assign these tasks to different people if you choose. (If you’re wondering, the permission for Extended Events is ALTER ANY EVENT SESSION, which is covered by CONTROL SERVER.) </li> </ul>  <h2>Action Mapping</h2>  <p>The table dbo.trace_xe_action_map exists in the master database with the following structure:</p>  <table border="1" cellspacing="0" cellpadding="0"><tbody>     <tr>       <td valign="top" width="77">         <p><strong>Column_name</strong></p>       </td>        <td valign="top" width="47">         <p><strong>Type</strong></p>       </td>     </tr>      <tr>       <td valign="top" width="77">         <p>trace_column_id</p>       </td>        <td valign="top" width="47">         <p>smallint</p>       </td>     </tr>      <tr>       <td valign="top" width="77">         <p>package_name</p>       </td>        <td valign="top" width="47">         <p>nvarchar</p>       </td>     </tr>      <tr>       <td valign="top" width="77">         <p>xe_action_name</p>       </td>        <td valign="top" width="47">         <p>nvarchar</p>       </td>     </tr>   </tbody></table>  <p>You can find more details by joining this to sys.trace_columns on the trace_column_id field.</p>  <blockquote>   <p><font color="#c0c0c0">SELECT        <br />&#160;&#160;&#160; c.trace_column_id,         <br />&#160;&#160;&#160; c.name [column_name],         <br />&#160;&#160;&#160; a.package_name,         <br />&#160;&#160;&#160; a.xe_action_name         <br />FROM sys.trace_columns c INNER JOIN&#160;&#160;&#160; dbo.trace_xe_action_map a         <br />&#160;&#160;&#160; ON c.trace_column_id = a.trace_column_id</font></p> </blockquote>  <p>If you examine this list, you’ll notice that there are relatively few Actions that map to SQL Trace Columns given the number of Columns that exist. This is not because we forgot to migrate all the Columns, but because much of the data for individual Event Classes is included as part of the EventData fields of the equivalent Events so there is no need to specify them as Actions.</p>  <h3></h3>  <h2>Putting it all together</h2>  <p>If you’ve spent a bunch of time figuring out the inner workings of SQL Trace, and who hasn’t, then you probably know that the typically set of Columns you find associated with any given Event Class in SQL Profiler is not fix, but is determine by the contents of the table sys.trace_event_bindings. We’ve used this table along with the mapping tables to produce a list of Event + Action combinations that duplicate the SQL Profiler Event Class definitions using the following query, which you can also find in the Books Online topic <a href="http://msdn.microsoft.com/en-us/library/ff878264(SQL.110).aspx" target="_blank">How To: View the Extended Events Equivalents to SQL Trace Event Classes</a>.</p>  <blockquote>   <p><font color="#c0c0c0">USE MASTER;        <br />GO         <br />SELECT DISTINCT         <br />&#160;&#160; tb.trace_event_id,         <br />&#160;&#160; te.name AS 'Event Class',         <br />&#160;&#160; em.package_name AS 'Package',         <br />&#160;&#160; em.xe_event_name AS 'XEvent Name',         <br />&#160;&#160; tb.trace_column_id,         <br />&#160;&#160; tc.name AS 'SQL Trace Column',         <br />&#160;&#160; am.xe_action_name as 'Extended Events action'         <br />FROM (sys.trace_events te LEFT OUTER JOIN dbo.trace_xe_event_map em         <br />&#160;&#160; ON te.trace_event_id = em.trace_event_id) LEFT OUTER JOIN sys.trace_event_bindings tb         <br />&#160;&#160; ON em.trace_event_id = tb.trace_event_id LEFT OUTER JOIN sys.trace_columns tc         <br />&#160;&#160; ON tb.trace_column_id = tc.trace_column_id LEFT OUTER JOIN dbo.trace_xe_action_map am         <br />&#160;&#160; ON tc.trace_column_id = am.trace_column_id         <br />ORDER BY te.name, tc.name</font></p> </blockquote>  <p>As you might imagine, it’s also possible to map an existing trace definition to the equivalent event session by judicious use of fn_trace_geteventinfo joined with the two mapping tables. This query extracts the list of Events and Actions equivalent to the trace with ID = 1, which is most likely the Default Trace. You can find this query, along with a set of other queries and steps required to migrate your existing traces over to Extended Events in the Books Online topic <a href="http://msdn.microsoft.com/en-us/library/ff878114(SQL.110).aspx" target="_blank">How to: Convert an Existing SQL Trace Script to an Extended Events Session</a>.</p>  <blockquote>   <p><font color="#c0c0c0">USE MASTER;        <br />GO         <br />DECLARE @trace_id int         <br />SET @trace_id = 1         <br />SELECT DISTINCT el.eventid, em.package_name, em.xe_event_name AS 'event'         <br />&#160;&#160; , el.columnid, ec.xe_action_name AS 'action'         <br />FROM (sys.fn_trace_geteventinfo(@trace_id) AS el         <br />&#160;&#160; LEFT OUTER JOIN dbo.trace_xe_event_map AS em         <br />&#160;&#160;&#160;&#160;&#160; ON el.eventid = em.trace_event_id)         <br />LEFT OUTER JOIN dbo.trace_xe_action_map AS ec         <br />&#160;&#160; ON el.columnid = ec.trace_column_id         <br />WHERE em.xe_event_name IS NOT NULL AND ec.xe_action_name IS NOT NULL</font></p> </blockquote>  <p>You’ll notice in the output that the list doesn’t include any of the security audit Event Classes, as I wrote earlier, those were not migrated.</p>  <h1>But wait…there’s more!</h1>  <p>If this were an infomercial there’d by some obnoxious guy next to me blogging “Well Mike…that’s pretty neat, but I’m sure you can do more. Can’t you make it even easier to migrate from SQL Trace?”&#160; Needless to say, I’d blog back, in an overly excited way, “You bet I can' obnoxious blogger side-kick!” What I’ve got for you here is a Extended Events Team Blog only special – this tool will not be sold in any store; it’s a special offer for those of you reading the blog.</p>  <p>I’ve wrapped all the logic of pulling the configuration information out of an existing trace and and building the Extended Events DDL statement into a handy, dandy CLR stored procedure. Once you load the assembly and register the procedure you just supply the trace id (from sys.traces) and provide a name for the event session. Run the procedure and out pops the DDL required to create an equivalent session. Any aspects of the trace that could not be duplicated are included in comments within the DDL output.</p>  <p>This procedure does not actually create the event session – you need to copy the DDL out of the message tab and put it into a new query window to do that. It also requires an existing trace (but it doesn’t have to be running) to evaluate; there is no functionality to parse t-sql scripts. I’m not going to spend a bunch of time explaining the code here – the code is pretty well commented and hopefully easy to follow. If not, you can always post comments or hit the feedback button to send us some mail.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:3953a850-8ce5-40d5-bfb6-e219df34966d" class="wlWriterEditableSmartContent"><p>Sample code: <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/35/19/metablogapi/37302E00TraceToExotendedEventDDL_58F758F72E00cs" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-35-19-metablogapi/3730_2E00_TraceToExotendedEventDDL_5F00_58F758F7_2E00_cs" target="_blank">TraceToExtendedEventDDL</a></p></div>  <h2></h2>  <h2>&#160;</h2>  <h2>Installing the procedure</h2>  <p>Just in case you’re not familiar with installing CLR procedures…once you’ve compile the assembly you can load it using a script like this:</p>  <blockquote>   <p><font color="#c0c0c0">-- Context to master        <br />USE master         <br />GO </font></p>    <p><font color="#c0c0c0">-- Create the assembly from a shared location.        <br />CREATE ASSEMBLY TraceToXESessionConverter         <br />FROM 'C:\Temp\TraceToXEventSessionConverter.dll'         <br />WITH PERMISSION_SET = SAFE         <br />GO </font></p>    <p><font color="#c0c0c0">-- Create a stored procedure from the assembly.        <br />CREATE PROCEDURE CreateEventSessionFromTrace         <br />@trace_id int,         <br />@session_name nvarchar(max)         <br />AS         <br />EXTERNAL NAME TraceToXESessionConverter.StoredProcedures.ConvertTraceToExtendedEvent         <br />GO</font></p> </blockquote>  <h1></h1>  <p></p>  <p>Enjoy!</p>  <p>-Mike</p>]]></content:encoded>
    </item>
    <item>
      <title>Session memory – who’s this guy named Max and what’s he doing with my memory?</title>
      <link>https://docs.microsoft.com/archive/blogs/extended_events/session-memory-whos-this-guy-named-max-and-whats-he-doing-with-my-memory</link>
      <pubDate>Tue, 07 Dec 2010 15:12:00 GMT</pubDate>
      <dc:creator><![CDATA[Mike Wachal - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/extended_events/2010/12/07/session-memory-whos-this-guy-named-max-and-whats-he-doing-with-my-memory/</guid>
      <description><![CDATA[SQL Server MVP Jonathan Kehayias (blog) emailed me a question last week when he noticed that the...]]></description>
      <content:encoded><![CDATA[<p>SQL Server MVP Jonathan Kehayias (<a href="http://sqlblog.com/blogs/jonathan_kehayias/default.aspx" target="_blank">blog</a>) emailed me a question last week when he noticed that the total memory used by the buffers for an event session was larger than the value he specified for the MAX_MEMORY option in the CREATE EVENT SESSION DDL. The answer here seems like an excellent subject for me to kick-off my new &ldquo;401 &ndash; Internals&rdquo; tag that identifies posts where I pull back the curtains a bit and let you peek into what&rsquo;s going on inside the extended events engine.</p>
<p>In a previous post (<a href="http://blogs.msdn.com/b/extended_events/archive/2010/03/31/option-trading-getting-the-most-out-of-the-event-session-options.aspx" target="_blank">Option Trading: Getting the most out of the event session options</a>) I explained that we use a set of buffers to store the event data before&nbsp; we write the event data to asynchronous targets. The MAX_MEMORY along with the MEMORY_PARTITION_MODE defines how big each buffer will be. Theoretically, that means that I can predict the size of each buffer using the following formula:</p>
<blockquote>
<p>max memory / # of buffers = buffer size</p>
</blockquote>
<p>If it was that simple I wouldn&rsquo;t be writing this post.</p>
<h3>I&rsquo;ll take &ldquo;boundary&rdquo; for 64K Alex</h3>
<p>For a number of reasons that are beyond the scope of this blog, we create event buffers in 64K chunks. The result of this is that the buffer size indicated by the formula above is rounded up to the next 64K boundary and that is the size used to create the buffers. If you think visually, this means that the graph of your max_memory option compared to the actual buffer size that results will look like a set of stairs rather than a smooth line. You can see this behavior by looking at the output of dm_xe_sessions, specifically the fields related to the buffer sizes, over a range of different memory inputs:</p>
<p>Note: This test was run on a 2 core machine using per_cpu partitioning which results in 5 buffers. (Seem my previous post referenced above for the math behind buffer count.)</p>
<table style="width: 468px;" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="111">
<p><strong>input_memory_kb</strong></p>
</td>
<td valign="top" width="128">
<p><strong>total_regular_buffers</strong></p>
</td>
<td valign="top" width="121">
<p><strong>regular_buffer_size</strong></p>
</td>
<td valign="top" width="106">
<p><strong>total_buffer_size</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="111">
<p>637</p>
</td>
<td valign="top" width="128">
<p>5</p>
</td>
<td valign="top" width="121">
<p>130867</p>
</td>
<td valign="top" width="106">
<p>654335</p>
</td>
</tr>
<tr>
<td valign="top" width="111">
<p>638</p>
</td>
<td valign="top" width="128">
<p>5</p>
</td>
<td valign="top" width="121">
<p>130867</p>
</td>
<td valign="top" width="106">
<p>654335</p>
</td>
</tr>
<tr>
<td valign="top" width="111">
<p><span style="color: #008000;" color="#008000">639</span></p>
</td>
<td valign="top" width="128">
<p><span style="color: #008000;" color="#008000">5</span></p>
</td>
<td valign="top" width="121">
<p><span style="color: #008000;" color="#008000">130867</span></p>
</td>
<td valign="top" width="106">
<p><span style="color: #008000;" color="#008000">654335</span></p>
</td>
</tr>
<tr>
<td valign="top" width="111">
<p><span style="color: #800080;" color="#800080">640</span></p>
</td>
<td valign="top" width="128">
<p><span style="color: #800080;" color="#800080">5</span></p>
</td>
<td valign="top" width="121">
<p><span style="color: #800080;" color="#800080">196403</span></p>
</td>
<td valign="top" width="106">
<p><span style="color: #800080;" color="#800080">982015</span></p>
</td>
</tr>
<tr>
<td valign="top" width="111">
<p>641</p>
</td>
<td valign="top" width="128">
<p>5</p>
</td>
<td valign="top" width="121">
<p>196403</p>
</td>
<td valign="top" width="106">
<p>982015</p>
</td>
</tr>
<tr>
<td valign="top" width="111">
<p>642</p>
</td>
<td valign="top" width="128">
<p>5</p>
</td>
<td valign="top" width="121">
<p>196403</p>
</td>
<td valign="top" width="106">
<p>982015</p>
</td>
</tr>
</tbody>
</table>
<p>This is just a segment of the results that shows one of the &ldquo;jumps&rdquo; between the buffer boundary at 639 KB and 640 KB. You can verify the size boundary by doing the math on the regular_buffer_size field, which is returned in bytes:</p>
<blockquote>
<p>196403 &ndash; 130867 = 65536 bytes</p>
<p>65536 / 1024 = 64 KB</p>
</blockquote>
<p>The relationship between the input for max_memory and when the regular_buffer_size is going to jump from one 64K boundary to the next is going to change based on the number of buffers being created. The number of buffers is dependent on the partition mode you choose. If you choose any partition mode other than NONE, the number of buffers will depend on your hardware configuration. (Again, see the earlier post referenced above.) With the default partition mode of none, you always get three buffers, regardless of machine configuration, so I generated a &ldquo;range table&rdquo; for max_memory settings between 1 KB and 4096 KB as an example.</p>
<table style="width: 597px;" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="128">
<p><strong>start_memory_range_kb</strong></p>
</td>
<td valign="top" width="128">
<p><strong>end_memory_range_kb</strong></p>
</td>
<td valign="top" width="128">
<p><strong>total_regular_buffers</strong></p>
</td>
<td valign="top" width="128">
<p><strong>regular_buffer_size</strong></p>
</td>
<td valign="top" width="83">
<p><strong>total_buffer_size</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>1</p>
</td>
<td valign="top" width="128">
<p>191</p>
</td>
<td valign="top" width="128">
<p>NULL</p>
</td>
<td valign="top" width="128">
<p>NULL</p>
</td>
<td valign="top" width="83">
<p>NULL</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>192</p>
</td>
<td valign="top" width="128">
<p>383</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>130867</p>
</td>
<td valign="top" width="83">
<p>392601</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>384</p>
</td>
<td valign="top" width="128">
<p>575</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>196403</p>
</td>
<td valign="top" width="83">
<p>589209</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p><span style="color: #008000;" color="#008000">576</span></p>
</td>
<td valign="top" width="128">
<p><span style="color: #008000;" color="#008000">767</span></p>
</td>
<td valign="top" width="128">
<p><span style="color: #008000;" color="#008000">3</span></p>
</td>
<td valign="top" width="128">
<p><span style="color: #008000;" color="#008000">261939</span></p>
</td>
<td valign="top" width="83">
<p><span style="color: #008000;" color="#008000">785817</span></p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>768</p>
</td>
<td valign="top" width="128">
<p>959</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>327475</p>
</td>
<td valign="top" width="83">
<p>982425</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>960</p>
</td>
<td valign="top" width="128">
<p>1151</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>393011</p>
</td>
<td valign="top" width="83">
<p>1179033</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>1152</p>
</td>
<td valign="top" width="128">
<p>1343</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>458547</p>
</td>
<td valign="top" width="83">
<p>1375641</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>1344</p>
</td>
<td valign="top" width="128">
<p>1535</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>524083</p>
</td>
<td valign="top" width="83">
<p>1572249</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>1536</p>
</td>
<td valign="top" width="128">
<p>1727</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>589619</p>
</td>
<td valign="top" width="83">
<p>1768857</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>1728</p>
</td>
<td valign="top" width="128">
<p>1919</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>655155</p>
</td>
<td valign="top" width="83">
<p>1965465</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>1920</p>
</td>
<td valign="top" width="128">
<p>2111</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>720691</p>
</td>
<td valign="top" width="83">
<p>2162073</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>2112</p>
</td>
<td valign="top" width="128">
<p>2303</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>786227</p>
</td>
<td valign="top" width="83">
<p>2358681</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>2304</p>
</td>
<td valign="top" width="128">
<p>2495</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>851763</p>
</td>
<td valign="top" width="83">
<p>2555289</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>2496</p>
</td>
<td valign="top" width="128">
<p>2687</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>917299</p>
</td>
<td valign="top" width="83">
<p>2751897</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>2688</p>
</td>
<td valign="top" width="128">
<p>2879</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>982835</p>
</td>
<td valign="top" width="83">
<p>2948505</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>2880</p>
</td>
<td valign="top" width="128">
<p>3071</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1048371</p>
</td>
<td valign="top" width="83">
<p>3145113</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>3072</p>
</td>
<td valign="top" width="128">
<p>3263</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1113907</p>
</td>
<td valign="top" width="83">
<p>3341721</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>3264</p>
</td>
<td valign="top" width="128">
<p>3455</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1179443</p>
</td>
<td valign="top" width="83">
<p>3538329</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>3456</p>
</td>
<td valign="top" width="128">
<p>3647</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1244979</p>
</td>
<td valign="top" width="83">
<p>3734937</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>3648</p>
</td>
<td valign="top" width="128">
<p>3839</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1310515</p>
</td>
<td valign="top" width="83">
<p>3931545</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>3840</p>
</td>
<td valign="top" width="128">
<p>4031</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1376051</p>
</td>
<td valign="top" width="83">
<p>4128153</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>4032</p>
</td>
<td valign="top" width="128">
<p>4096</p>
</td>
<td valign="top" width="128">
<p>3</p>
</td>
<td valign="top" width="128">
<p>1441587</p>
</td>
<td valign="top" width="83">
<p>4324761</p>
</td>
</tr>
</tbody>
</table>
<p>As you can see, there are 21 &ldquo;steps&rdquo; within this range and max_memory values below 192 KB fall below the 64K per buffer limit so they generate an error when you attempt to specify them.</p>
<p><strong>Clarification: </strong>I got another question about this topic last week, this time from a student in one of Jonathan Kehayias' classes. Someone noticed that if you take the size of the buffer (regular_buffer_size) and divide that by 64 KB you don't get the nice even boundary that I am claiming above and that someone is wondering "What gives?". A reasonable question.</p>
<p>What gives is that regular_buffer_size is reporting the usable buffer space, or the space left after we subtract a small amount of memory for the overhead of managing the buffers. You'll notice that if you take any regular_buffer_size and divide it by 64 KB you'll have the same fraction left over every time: 0.99687194824219, that's the overhead.</p>
<h3>Max approximates True as memory approaches 64K</h3>
<p>The upshot of this is that the max_memory option does not imply a contract for the maximum memory that will be used for the session buffers (Those of you who read <a href="http://blogs.msdn.com/b/extended_events/archive/2010/06/28/take-it-to-the-max-and-beyond.aspx" target="_blank">Take it to the Max (and beyond)</a> know that max_memory is really only referring to the event session buffer memory.) but is more of an estimate of total buffer size to the nearest higher multiple of 64K times the number of buffers you have. The maximum delta between your initial max_memory setting and the true total buffer size occurs right after you break through a 64K boundary, for example if you set max_memory = 576 KB (see the green line in the table), your actual buffer size will be closer to 767 KB in a non-partitioned event session. You get &ldquo;stepped up&rdquo; for every 191 KB block of initial max_memory which isn&rsquo;t likely to cause a problem for most machines.</p>
<p>Things get more interesting when you consider a partitioned event session on a computer that has a large number of logical CPUs or NUMA nodes. Since each buffer gets &ldquo;stepped up&rdquo; when you break a boundary, the delta can get much larger because it&rsquo;s multiplied by the number of buffers. For example, a machine with 64 logical CPUs will have 160 buffers using per_cpu partitioning or if you have 8 NUMA nodes configured on that machine you would have 24 buffers when using per_node. If you&rsquo;ve just broken through a 64K boundary and get &ldquo;stepped up&rdquo; to the next buffer size you&rsquo;ll end up with total buffer size approximately 10240 KB and 1536 KB respectively (64K * # of buffers) larger than max_memory value you might think you&rsquo;re getting. Using per_cpu partitioning on large machine has the most impact because of the large number of buffers created. If the amount of memory being used by your system within these ranges is important to you then this is something worth paying attention to and considering when you configure your event sessions.</p>
<p>The DMV dm_xe_sessions is the tool to use to identify the exact buffer size for your sessions. In addition to the regular buffers (read: event session buffers) you&rsquo;ll also see the details for large buffers if you have configured MAX_EVENT_SIZE. The &ldquo;buffer steps&rdquo; for any given hardware configuration should be static within each partition mode so if you want to have a handy reference available when you configure your event sessions you can use the following code to generate a range table similar to the one above that is applicable for your specific machine and chosen partition mode.</p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">DECLARE @buf_size_output table (input_memory_kb bigint, total_regular_buffers bigint, regular_buffer_size bigint, total_buffer_size bigint) <br />DECLARE @buf_size int, @part_mode varchar(8) <br />SET @buf_size = 1 -- Set to the begining of your max_memory range (KB) <br />SET @part_mode = 'per_cpu' -- Set to the partition mode for the table you want to generate </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">WHILE @buf_size &lt;= 4096 -- Set to the end of your max_memory range (KB) <br />BEGIN <br />&nbsp;&nbsp;&nbsp; BEGIN TRY </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF EXISTS (SELECT * from sys.server_event_sessions WHERE name = 'buffer_size_test') <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DROP EVENT SESSION buffer_size_test ON SERVER <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @session nvarchar(max) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET @session = 'create event session buffer_size_test on server <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add event sql_statement_completed <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add target ring_buffer <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; with (max_memory = ' + CAST(@buf_size as nvarchar(4)) + ' KB, memory_partition_mode = ' + @part_mode + ')' </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXEC sp_executesql @session </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET @session = 'alter event session buffer_size_test on server <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state = start' </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXEC sp_executesql @session </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSERT @buf_size_output (input_memory_kb, total_regular_buffers, regular_buffer_size, total_buffer_size) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @buf_size, total_regular_buffers, regular_buffer_size, total_buffer_size FROM sys.dm_xe_sessions WHERE name = 'buffer_size_test' <br />&nbsp;&nbsp;&nbsp; END TRY <br />&nbsp;&nbsp;&nbsp; BEGIN CATCH <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSERT @buf_size_output (input_memory_kb) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @buf_size <br />&nbsp;&nbsp;&nbsp; END CATCH <br />&nbsp;&nbsp;&nbsp; SET @buf_size = @buf_size + 1 <br />END </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">DROP EVENT SESSION buffer_size_test ON SERVER </span></p>
<p><span style="color: #c0c0c0;" color="#c0c0c0">SELECT MIN(input_memory_kb) start_memory_range_kb, MAX(input_memory_kb) end_memory_range_kb, total_regular_buffers, regular_buffer_size, total_buffer_size from @buf_size_output group by total_regular_buffers, regular_buffer_size, total_buffer_size</span></p>
<p>Thanks to Jonathan for an interesting question and a chance to explore some of the details of Extended Event internals.</p>
<p>- Mike</p>]]></content:encoded>
    </item>
  </channel>
</rss>