Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Tips Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS Access
SQL Scripts & Samples
» Database Forum
» Slideshows
» Sitemap
Free Newsletters:

News Via RSS Feed

Database Journal |DBA Support |SQLCourse |SQLCourse2

Featured Database Articles


Posted Jul 30, 2003

Scripting Traces for Performance Monitoring on SQL Server - Page 2

By Andrew Novick

Creating the Trace Script

To create the trace, fire up SQL Profiler and use it to define the trace. You do not have to do anything special to create the trace but completing a few fields in the GUI makes life easier. Normally, when you use the Trace Properties Form to ask that the trace sent to a file and not to SQL Profiler's screen, you select a "server trace." Do that and fill in a file name when it asks. You should use the fields at the bottom of the General tab to "Enable trace stop time" and fill in a time. Do not worry what time to stop at; it will be changed when the stored procedure is created.

Figure 1 shows the General tab as I used SQL Profiler to create the trace. I started with the SQLStandard.trc trace template and specified "Save to file" and a trace stop time.

Figure 1 SQL Profiler's General Tab

The actual contents of the other tabs are not critical to understanding the scripting technique because when SQL Profiler creates the script, it is going to add the events, data columns and filters that you ask for. In this case, among other things, I am looking for table scans, lock deadlocks and statements that take over 100 milliseconds to execute.

There is a little bit of a trick to setting up the filter: all conditions are combined with the AND operator. That is, the trace only records an event when all the expressions in the filter are satisfied. To make sure that the script does not filter out too much, I have used a 100-millisecond filter on duration, not CPU time because deadlocks do not consume CPU, they just make a query run until the deadlock timeout.

Once you are satisfied with the definition of the trace, run it, stop it and then use SQL Profiler's menu command File -> Script Trace -> For SQL Server 2000. When asked, give it a file name to save the script. The following listing shows the first few lines of the output:

/* Created by: SQL Profiler                         */
/* Date: 07/14/2003  04:29:56 PM         */

-- Create a Queue
declare @rc int
declare @TraceID int
declare @maxfilesize bigint
declare @DateTime datetime

set @DateTime = '2003-07-14 18:29:20.000'
set @maxfilesize = 5
exec @rc = sp_trace_create @TraceID output, 2
           , N'\\NSL2\Projects\Article2.trc', @maxfilesize, @Datetime
if (@rc != 0) goto error

-- Client side File and Table cannot be scripted

-- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 10, 1, @on
exec sp_trace_setevent @TraceID, 10, 12, @on
exec sp_trace_setevent @TraceID, 10, 13, @on

SQL Profiler creates a script that duplicates the trace that you specified using the GUI screens.

The script to add all the events and columns to the trace runs on for several pages and there is no need to look at more than the first few lines. However, it's a script, or batch, not a stored procedure. There is some work to turn it into a more usable form. That's the next task. These are the requirements:

  • Turn the script into a stored procedure that can be run at any time.
  • The proc should take the duration to run the trace.
  • Create an output file name that is sure to be unique.
  • Set the trace end time based on the current time and the duration that is requested.

All three parts are pretty easy. I name the stored procedure dba_Trc_Northwind1 to distinguish it from any other traces that I might be running. Creating a unique file name based on the time is not particularly difficult either. To insure uniqueness put the date and time into the file name in a form that is both a valid file name, one without colons or slashes, and one that sorts based on the date and time. I have used a UDF, udf_DT_FilenameFmt, from my library to form the name. You can get the UDF from a recent issue of my T-SQL UDF of the Week newsletter at this URL: http://www.novicksoftware.com/UDFofWeek/Vol1/T-SQL-UDF-Volume-1-Number-36-udf_dt_filenamefmt.htm.

After adding the stored procedure header and the code to calculate the end time, the top of the trace looks like the listing that follows. The shaded area calculates the file name and trace stop time before calling sp_trace_create to begin the process that defines the trace.

CREATE PROCEDURE dba_Trc_Northwind1 

    @Sec int = 600 -- Duration in seconds for the trace
  , @TraceID int OUTPUT -- Return the TraceID to the caller.
* Creates a trace on the Northwind database.
declare @rc int
declare @dbaTraceID int
declare @maxfilesize bigint
declare @DateTime datetime
DECLARE @FileName nvarchar(256)
      , @StartDT  datetime -- When the trace started

SELECT @StartDT = getdate()
SELECT @FileName = N'\\NSL2\Projects\Northwind1-' + dbo.udf_DT_FileNameFmt (getdate(), 1, 1) , @DateTime = DATEADD (s, @Sec, @StartDT) set @maxfilesize = 5 exec @rc = sp_trace_create @TraceID output, 2, @FileName , @maxfilesize, @Datetime
if (@rc != 0) goto error -- Set the events declare @on bit set @on = 1 exec sp_trace_setevent @TraceID, 10, 1, @on exec sp_trace_setevent @TraceID, 10, 12, @on

Later in the day, when activity has died down, the trace file will be loaded into a table for analysis. To facilitate that process and for keeping track of the traces, the file name, start time, person responsible, and a comment for each trace is recorded in the table dbaTrace. Here is the script to create it:

CREATE TABLE dbo.dbaTrace (
    dbaTraceID int IDENTITY (1, 1) NOT NULL ,
    TraceID int NOT NULL ,
    StartDT datetime NOT NULL ,
    EndDT datetime NOT NULL ,
    [FileName] nvarchar (255)  NULL ,
    FileLoadedDT datetime NULL ,
    Responsible nvarchar (128)  NULL ,
    Description nvarchar (255)  NULL 

The bottom portion of the stored procedure takes care of inserting a row in the dbaTrace table by calling the stored procedure dba_Trc_Record. There is the last dozen or so lines of dba_Trc_Northwind1:

-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
-- select TraceID=@TraceID

EXEC @RC = dba_Trc_Record @Filename, @StartDT, @Sec, 'Andy'
                , 'Scripted Trace for Northwind scans and deadlocks'
                , @TraceID, @dbaTraceID OUTPUT
PRINT 'Recording Started. SQL Trace ID=' + CONVERT(varchar(9), @TraceID) PRINT 'dbaTrace.dbaTraceID = ' + CONVERT(varchar(9), @dbaTraceID)
goto finish error: select ErrorCode=@rc finish:

Since this stored procedure is going to be invoked by a SQL Job, PRINT statements are the way to get information into the log of the Job step that invokes it. That is why I commented out the "select TraceID=@TraceID" statement. Instead, the two PRINT statements in the shaded area show SQL Server's ID for the trace and dbaTraceID, which is the key to the dbaTrace table.

The job is real simple. Just one step that invokes dba_Trc_Northwind1 and supplies the number of seconds for the trace: Here's the text of the only step:

DECLARE @rc int, @dbaTraceID int
exec @rc = dba_Trc_Northwind1 600, @dbaTraceID OUTPUT
PRINT 'RC from starting Trace = ' + convert(varchar(9), @rc)
PRINT 'DBA TraceID = ' + convert(varchar(9), @dbaTraceID)

I have used 600 seconds for 10 minutes of monitoring. During a period of heavy activity, that seems to be sufficient.

MS SQL Archives

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Latest Forum Threads
MS SQL Forum
Topic By Replies Updated
SQL 2005: SSIS: Error using SQL Server credentials poverty 3 August 17th, 07:43 AM
Need help changing table contents nkawtg 1 August 17th, 03:02 AM
SQL Server Memory confifuration bhosalenarayan 2 August 14th, 05:33 AM
SQL Server Primary Key and a Unique Key katty.jonh 2 July 25th, 10:36 AM