使用Trace Management Object监测和诊断SQL Server(二)

在这篇文章中我们将介绍一个replay trace的示例,通过重放抓到的trace文件来诊断应用程序在SQL Server上运行是否有问题。

Replay trace示例

这个例子模仿你使用Profiler工具对抓到的trace文件进行重放,从而对SQL Server及你的应用程序进行诊断的过程。下面是详细的步骤和描述。

1、TraceReplay类是对trace file或trace table进行重放的关键类,你需要设置TraceReplay的三个属性,Connection属性代表你将在哪个数据库实例上进行重放,Source属性代表重放哪个文件或数据表,OutputFile代表重放的结果将输出到哪个文件,你也可以使用OutputTable属性指定将重放结果输出到数据表中。下面的代码将使用capture trace例子里抓到的trace file作为重放的输入并将结果存为traceoutput.trc文件。

TraceReplay replay = new TraceReplay();
SqlConnectionInfo connInfo = new SqlConnectionInfo(".");
connInfo.UseIntegratedSecurity = true;
replay.Connection = connInfo;
TraceFile traceFile = new TraceFile();
traceFile.InitializeAsReader(@"c:\tracefile.trc");
replay.Source = traceFile;
TraceFile traceFileOutput = new TraceFile();
traceFileOutput.InitializeAsReplayOutputWriter(@"c:\replayoutput.trc");
replay.OutputFile = traceFileOutput;

2、TraceReplay类还有个比较重要的属性Options,你可以通过设置Options属性来控制如何重放。Options属性是个TraceReplayOptions对象,Profiler工具中重放配置对话框上的很多配置项都可以通过Options属性来设置。下面的代码中设置了3个属性,Mode设置重放模式为连接层面上同步(另一个模式为SequentialReplay,指在所有连接上完全同步),NumberOfReplayThreads设置重放的线程数为2,KeepResults将控制在重放结果文件中是否出现SQL等的执行结果,比如你的trace里有select 1语句,那设置KeepResults为false将避免在结果文件中出现select 1返回的result set。

replay.Options.Mode = ReplayMode.ConnectionLevelSync;
replay.Options.NumberOfReplayThreads = 2;
replay.Options.KeepResults = false;

3、TraceReplay类提供了5个事件,你可以通过提供你自己的event handler来进一步控制重放操作,其中最有用的event是ReplayEvent,它将在每个event被重放之前调用,你可以控制是否跳过该event的重放。下面的代码在设置了ReplayEvent的处理函数后启动重放。请注意Start函数是同步操作,它将一直阻塞直到重放结束,所以如果你需要在中途停掉的话,你可以在event handler里或者其它线程中调用Stop函数。 

replay.ReplayEvent += new ReplayEventHandler(ReplayHandler);
replay.Start();
traceFile.Close();

4、这里我们的ReplayHandler处理函数将对SPID进行过滤,所有SPID不是54的事件都将被忽略。代码中空的catch是为了避免某些event不含有SPID列会造成读取该列失败。 

private static void ReplayHandler(Object sender, ReplayEventArgs args)
{
    IDataRecordChanger recordChanger = args.CurrentRecord;
    int spid = 0;
    try
    {
        spid = (int)recordChanger["SPID"];
    }
    catch { }
    if (spid != 54)
        args.SkipRecord = true;
}

5、Replay的结果文件可以用Profiler工具打开查看,当然你仍然可以通过TraceFile打开,只要简单的调用InitializeAsReader然后循环调用Read即可,下面的代码将打出TextData列的内容。

TraceFile traceFileOutput = new TraceFile();
traceFileOutput.InitializeAsReader(@"c:\replayoutput.trc");
while (traceFileOutput.Read())
{
Console.WriteLine(traceFileOutput["TextData"]);
}

软件开发工程师 徐进

TMODemo.zip