SQL Server Extended Events 进阶 2:使用UI创建基本的事件会话
第一阶中我们描述了如何在Profiler中自定义一个Trace,并且让它运行在服务器端来创建一个Trace文件。然后我们通过Jonathan Kehayias的 sp_SQLskills_ConvertTraceToExtendedEvents存储过程,将Trace定义转换为创建Extended Events 会话的脚本。希望它为你建立起了一座由SQL Trace 通向Extended Events开始的桥梁。当然,它也提供了一个将已有SQL Trace库转换为Extend Events的有效途径。
然而,当我们需要创建一个新的Extended Events会话时改怎么办呢,从头开始?是的,我们我可以使用T-Sql定义会话,但是在SQL Server2012及以后版本中,UI工具已经集成在SSMS中,我们可以使用它定义事件会话,开始,停止它们,同时也可以直接在SMSS UI上直接使用和分析这些数据。
在这一阶中,我们将介绍New Session对话框的基本使用方法,使用它创建一个新的事件会话,定义它的事件,Actions和谓词,并且建立一个事件会话的目标用于收集事件的数据。
从UI开始
在SQL server 2008以及SQL Server 2008R2中并没有为Extended Events集成的UI。如果你正使用这些版本,你可以选择使用T-SQL定义事件会话,或者安装 Jonathan Kehayias的SSMS插件(http://extendedeventmanager.codeplex.com/))。如果你使用2012 Management Studio,你可以连接SQL Server的早期版本,但是对于2008 和2008R2 版本的实例,你并不能找到Extended Events UI。Jonathan 为SSMS 2012 提供了一个独立的插件,它提供了一个简单的UI用与连接2008和2008R2。
由于在SQL server 2008和2008R2缺少UI,这也意味着我们必须使用T-SQL和XQuery来处理事件数据。然而幸运的是在SQL server 2012的UI中我们可以读取由2008和2008R2生成的目标文件,因此值得安装SSMS 2012和使用它的UI分析事件数据。
为了这一阶剩余的部分便于理解,我假设你正在使用SQL Server 2012及以上版本UI。为了在SSMS中访问Extended Events,请展开SQL实例,在对象浏览器中,切换至Management | Extended Events,并展开Sessions,我们可以看到实例中已存在的事件会话。
如果你已经完成了第一阶,你应该可以看到两个内置的Extended Events会话AlwaysOn_health 和system_health,加上我们创建的 XE_ReadsFilter_Trace会话。
Figure 1: Viewing event sessions in the SSMS UI
就像我们在第一阶中所提及的,Extended events的好处之一就是会话定义被保存在服务器元数据中,即使实例被重启也是被持久化的。Trace的定义却不是这样,我们不得不实现一个自定义的存储过程,用于在实例重启后再次创建Trace。
我们也可以有很多事件会话,但却不激活它们。这点虽在Trace中也是可行的,但是我们通常不会这样用,这可能是由于输出目标文件名是硬编码在Trace定义中的。当我们想要停止或重启Trace时,我们需要保证输出文件在启动前被删除,或为Trace设置滚动文件更新。Extended Events解决了这一问题,我们在这一阶中 数据存储页:定义目标中介绍。
XE_ReadsFilter_Trace 会话上右键菜单中选择Script Session as | CREATE TO | New Query Editor Window,事件会话定义会被输出至一个新的查询窗口,如Listing1所示。这段代码与在第一阶中使用sp_SQLskills_ConvertTraceToExtendedEvents所生成的功能相同。然而你会注意到这里有一些细小的不同点。首先,这个SQL Server存储的脚本定义中已经不再包含那些用于映射SQL Trace列的代码注释了。
其次,SQL Server在脚本末尾的With子句中包含了一些我们没有见过的额外的选项(在下一阶中介绍)。所有会话选项都是默认值,这也是在再第一阶中 Trace转化中没有生成他们的原因。
CREATE EVENT SESSION [XE_ReadsFilter_Trace] ON SERVER ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name , sqlserver.database_id , sqlserver.server_instance_name , sqlserver.session_id ) WHERE ( logical_reads >= 10000 ) ), ADD EVENT sqlserver.sql_statement_completed ( ACTION ( sqlserver.client_app_name , sqlserver.database_id , sqlserver.server_instance_name , sqlserver.session_id ) WHERE ( logical_reads >= 10000 ) ) ADD TARGET package0.event_file ( SET filename = 'C:\temp\XE_ReadsFilter_Trace.xel' , max_file_size = ( 5 ) , max_rollover_files = ( 1 ) ) WITH ( MAX_MEMORY = 4096 KB , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS , MAX_DISPATCH_LATENCY = 30 SECONDS , MAX_EVENT_SIZE = 0 KB , MEMORY_PARTITION_MODE = NONE , TRACK_CAUSALITY = OFF , STARTUP_STATE = OFF ) GO
Listing 1: Scripting out the existing XE_ReadsFilter_Trace event session
我们接下来使用UI来创建一个与XE_ReadsFilter_Trace具有相同的事件,Actions,谓词的事件会话,但是不同名。在这个过程的最后,我会讲述如何将我们在UI上完成的功能定义,转为SQL Server 生成的T-SQL脚本。
在UI上创建一个新的事件会话
我们可以是使用New Session Wizard向导或New Session对话框来创建事件会话。然而,这个向导只是New Session对话框中选项的一个子集,因此它不是很有用。因而,我们着重关注New Session对话框。
创建一个Extended Events会话,只需右键点击Sessions 文件夹并选择New Session...。一个具有四个属性页的New Session对话框会显示出来,四个属性页分别是:General,Evetns,Data Storage和Advanced,我们从General页开始。
基本会话属性
在会话General属性页上,我们可以输入一个会话名称。开启一些会话的其他选项,如创建完成后立即启动,我们可以使用显示实时视图查看事件数据。
输入会话名称,如“HighReadQueries ”来区别我们在第一阶中创建的会话,会话名称必须是唯一的。
Figure 2: The General properties page of the New Session dialog
如果你看不到Causality tracking这个选项可能是因为对话框太小了,这个高级选项不会再这涵盖在这一阶中。一个正确是UI设计应该是显示一个下拉条以防我们不能看到整个屏幕。
Events 页
下一步是向我们的会话中添加一些事件。这个例子中,我们想要添加两个事件sqlserver.sql_statement_completed和sqlserver.rpc_completed。Events页中我唯一喜欢的是我们可以搜索事件库。我敢打赌你曾经花过几分钟,几小时,甚至几天时间在Profiler的事件列表中查看那180个事件,仅仅为了一个你所需要的事件。在Extended Events UI上这已不再是问题了,我们可以根据事件名称,描述,事件字段或者全部条件来搜索。
在事件库的文本框中输入completed,对话框会动态过滤这个列表,最后仅剩15个事件。
Figure 3: Handy event name filtering when searching the event library
请注意 Category/Channel 这两种事件分类,它们是基于Windows 系统Events Tracing的Keyword/Channel分类。我们不会在这一阶讨论。
在这我们不会看到所有的"_completed"事件,默认设置中,UI不会显示Debug Channel事件。选择Channel下拉框,你会看到Debug没有被选中。如果你启用它,你会看到更多的_completed事件粗线在列表中,Debug事件是为微软内部在生产环境下使用的。一些专家可能会使用他们做高级的故障诊断,或者为了更好的理解SQL Server内部的工作机制。然而,微软并不为这种方式提供支持,也不保证他们的行为,这些事件也可能在下一个release中被删除或更改。
双击rpc_completed 和sql_statement_completed 事件,他们会出现在Selected events面板中,然后选择Configure按钮为这些事件添加Actions和谓词。
Figure 4: Adding events to the event session
这是New Session对话框中我不喜欢的一点:配置事件不在同一面板中,必须点击Configure按钮来切换到Action和谓词选项。
配置事件
事件配置选项中有三个标签页:Global Fields (Actions), Filter (Predicate) and Event Fields。
默认负载(Event Fields)
Event Fields标签页显示了事件默认负载的事件字段(数据列)。
Figure 5: The default payload for an event
切换这两个事件你会看到不同的时间默认捕获的数据也不相同。大多数的字段不能从这个集合中移除,但是那些带有复选框的是可选的。例如,以pc_completed事件为例,statement 是可选的,但是默认会被收集,而output_parameters 字段也是可选的但是默认不会被收集。
不要对Event Fields做改动,保持他们收集事件正常的,默认的负载。
添加Actions
现在让我们根据休要来添加Actions,选择Global Fields(Acrtions)标签页。Actions 页被称为全局字段,因为这些字段并不是属于任何单独事件的。
添加Actions到事件中仅需要勾选列名前的复选框。想要为多个事件添加Actions, 可以在左边同时选中多个事件。这个例子中,我们需要为这两个事件添加client_app_name, database_id, server_instance_name, 和session_id。
Figure 6: Adding actions to event
上述选择的Actions在收集字段的场景中是非常友好的,仅仅提供额外事件的详细信息。
Extended Events也提供了一些具有副作用Actions,为称为side-effecting actions。例如,debug_break 当事件触发时,会触引起调试中断。create_dump_all_threads和create_dump_single_thread分别会造成SQL Server为所有线程或单个线程创建内存Dump。数据库引擎在同一线程中执行这些Action,因此这些Actions可能急剧影响性能,我们应该小心使用它们,我们会在下一阶中进一步讨论。
设置过滤(谓词)
最后我们选择Filter (Predicate)标签页来设置谓词。尽在少数例外情况下,你才应该为每个事件单独配置谓词。为了"short-circuit"(短路)事件判断,防止Extended Events引擎收集不需要的数据而造成的不必要的开销。谓词配置和"short-circuit"逻辑是非常重要的,我们会在下一阶中详细介绍。
这个例子中,选中这两个事件,从Filed下拉框中选择logical_reads,然后运算色湖之为大于等于,并在Value中设置10000。使用这个配置,我们的事件会话仅捕获那些执行过程消费大于10000个逻辑读的SQL语句或存储过程。
Figure 7: Adding a predicate
这个多选功能,为了使每个事件可以添加相同的谓词,Field下拉框中仅显示两个事件所共有的字段和Global字段。根据选择的事件,并不是所有的字段可选。例如,如果我们添加了 error_reported事件,然后选择这三个事件,我们在谓词选项中就不会在看到logical_reads ,如图8所示。
Figure 8: Adding a predicate to multiple events at the same time
这个例子中,我们为两个事件设置了相同的谓词,当然我们也有足够的灵活性为每个事件设置不同的谓词,这点事在SQL Trace中无法完成的。
此时的事件会话配置,我们就可以选择OK来创建会话了,因为只有添加至少一个事件是必须的条件。为会话指定目标文件并不是必要条件。
数据存储页:定义一个目标
选择Data Storage页并选择一个Event_file类型的目标。在File name on server文本框最后选择“Browse...”并选择目标输出文件路径。在2008和2008R2中,需要指定两个文件,一个为了日志数据(例如真正的事件数据),另外一个为元数据(用来描述日志文件中文件内容,因此事件和Actions可以被正确的转换)。在SQL Server 2012和更高版本中,只有一个文件被用到。
在SQL Server 2012中,完整的log文件夹路径显示在UI上(如: C:\Program Files\Microsoft SQL Server\MSSQL12.SQL2014\MSSQL\Log);在SQL Server 2014中仅仅显示一个文件名,但是SQL Server默认使用log文件夹路径。
文件名最大字符长度为260,在我们的例子中,我们使用C:\temp\HighReadQueries。并不需要为目标文件提供文件扩展名(.xel)。
Extended Event引擎会附加 _0_和一个整数(文件创建时间日期到1600-1-1所间隔的毫秒数)在文件名末尾来保证文件名总是唯一的。这与SQL非常不同,我们已经讨论过Trace文件名需要定义在Trace定义中。
event_file 目标提供了以MB设置最大文件大小,并允许滚动文件更新。如果你不指定文件最大值,文件会一直增长直至填满硬盘。
Figure 9: Selecting and configuring a target
高级会话选项
在Advanced页中,我们可以设置额外的高级会话选项。我们在下一阶中详细覆盖这些选项,这里不做讲解。在任何情况下,为了跟Level 1中创建的事件会话保持一致,我们会保持这些选项的默认值。
事件会话DDL
选择OK来创建会话,它会出现在Extended Events | Sessions 文件夹下,并且是Active状态,应为我们在General面板中勾选了"Start the event session immediately after session creation"。如需为事件会话生成T-SQL脚本,可以点击OK前选择UI上的Script按钮,也可以在创建会话后右键选择HighReadQueries,并选择“Script Session as”来生成脚本。在Listing2中,我已经为New Session创建的DDL脚本的每个段落添加了注释。
/*Create the session, named as specified on the General page*/ CREATE EVENT SESSION [HighReadQueries] ON SERVER /*Add and configure events, actions and predicates, as specified on the Events page*/ ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name, sqlserver.database_id, sqlserver.server_instance_name, sqlserver.session_id ) WHERE ( [logical_reads] >= ( 10000 ) ) ), ADD EVENT sqlserver.sql_statement_completed ( ACTION ( sqlserver.client_app_name, sqlserver.database_id, sqlserver.server_instance_name, sqlserver.session_id ) WHERE ( [logical_reads] >= ( 10000 ) ) ) /*Add and configure a target, as specified on the Data Storage page*/ ADD TARGET package0.event_file ( SET filename = N'C:\temp\HighReadQueries' ) /* Set Session-level options, specified on the General and Advanced pages*/ WITH ( MAX_MEMORY = 4096 KB , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS , MAX_DISPATCH_LATENCY = 30 SECONDS , MAX_EVENT_SIZE = 0 KB , MEMORY_PARTITION_MODE = NONE , TRACK_CAUSALITY = OFF , STARTUP_STATE = ON ); GO
Listing 2: The event session DDL for HighReadQueries
这段代码与我们在Listing1 中所见的XE_ReadsFilter_Trace会话几乎一致。另外为了立刻启动会话,我们也选择了“Watch live data on the screen as it is captured”。在SSMS中一个用户显示会话数据的窗口会被打开,就像在Profiler UI上一样。这里一个重要的提升是,如果查看实时数据开销影响到系统性能时,查看器的连接会被自动断开。
总结
完成这一阶后,你应该对在SSMS中创建一个基本的会话很熟悉了,你可以捕获一个或多个事件,收集一系列的Actions,使用简单的谓词并保存数据到文件中。这些配置与在PRofiler或Trace中捕获信息是相似的,却又不相同。
下一阶中,我们会进一步深入extended events基础,使你可以从基本的数据收集转向高级配置和捕获。