+ 'Object Name: ' + ISNULL @objectName, 'No Object Given' + CHAR13 + 'Object Type: ' + ISNULL @objectType, 'No Type Given' + CHAR13 + '---'; EXEC msdb..sp_send_dbmail @profile_nam
Trang 1SET @data = EVENTDATA ()
SET @tsqlCommand =
EVENTDATA ().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1] ' 'nvarchar(max)')
SET @eventType =
EVENTDATA ().value('(/EVENT_INSTANCE/EventType)[1]','nvarchar(ma x)')
SET @serverName =
EVENTDATA ().value('(/EVENT_INSTANCE/ServerName)[1]','nvarchar(m ax)')
SET @loginName =
EVENTDATA ().value('(/EVENT_INSTANCE/LoginName)[1]','nvarchar(ma x)')
SET @userName =
EVENTDATA ().value('(/EVENT_INSTANCE/UserName)[1]','nvarchar(max )')
SET @databaseName =
EVENTDATA ().value('(/EVENT_INSTANCE/DatabaseName)[1]','nvarchar (max)')
SET @objectName =
EVENTDATA ().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(m ax)')
SET @objectType =
EVENTDATA ().value('(/EVENT_INSTANCE/ObjectType)[1]','nvarchar(m ax)')
SET @emailBody = + ' -'
CHAR(13)
+ '- DDL Trigger Activation Report -'
CHAR(13)
+ ' -'
CHAR(13)
+ 'Sql Command: '
ISNULL (@tsqlCommand, 'No Command Given') + CHAR(13)
+ 'Event Type: '
+ ISNULL (@eventType, 'No Event Type Given') + CHAR(13)
+ 'Server Name:
' ISNULL (@serverName, 'No Server Given') + CHAR(13)
+ 'Login Name: '
+ ISNULL (@loginName, 'No LOGIN Given') + CHAR(13)
+ 'User Name: '
+ ISNULL (@username, 'No User Name Given') + CHAR(13)
+ 'DB Name: '
+ ISNULL (@databaseName, 'No Database Given') + CHAR(13)
Trang 2+ 'Object Name: '
+ ISNULL (@objectName, 'No Object Given') + CHAR(13)
+ 'Object Type: '
+ ISNULL (@objectType, 'No Type Given') +
CHAR(13)
+ ' -'; EXEC msdb sp_send_dbmail @profile_name='Admin Profile',
@recipients= yourmail@yourmail.com', @subject='DDL Alteration Trigger', @body=@emailBody
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ENABLE TRIGGER [AuditDatabaseDDL] ON ALL SERVER
GO
Listing 7.8: DDL trigger for database creates and drops
With the trigger enabled, it is easy enough to test, simply by creating a database on the server (CREATE DATABASE TEST_TRIGGER) As expected, and as shown in Figure 7.5, the mail comes in and I can see the captured events, including the username that created the database, as well as the time
Figure 7.5: Mail from DDL trigger for database creation
Trang 3With only a slight modification to the DDL trigger, I can also be notified of any login creations on the server, with a simple addition of CREATE LOGIN to the FOR
statement of the CREATE TRIGGER statement:
CREATE TRIGGER [AuditDatabaseDDL]
ON ALL SERVER
FOR CREATE_DATABASE, DROP_DATABASE, CREATE LOGIN
Listing 7.9: Tracking login creation
With the new trigger in place I can attempt to also create a login, as shown in Listing 7.10
CREATE LOGIN RogerKennsingtonJones WITH PASSWORD
'MyPassword12'
Listing 7.10: RogerKensingtonJones, we know you exist Don't try anything funny
Again, as expected I receive the mail notification that the account has been created At that point, the reaction would be one of concern, but at least I know that I have several scripts available that will allow me to get to the bottom of who created this account, why, and what privileges it has
Server-side tracing
Most DBAs will have experienced the scenario whereby a red-faced program/development manager storms up to them and demands to know why his ultra-critical tables keep getting truncated, and who is doing it
The problem is that in order to get a complete picture of your server at a transactional level, you need either full time Profiler tracing, or to enable C2 level auditing; both of which come at a high cost These auditing tools will not only slow down your servers considerably, but the drive space required in order to keep
a record of each transaction on your server is daunting, at best
The solution I offer here presents a "lightweight" alternative It is rooted in the idea that issues in a system will inevitably show up more than once If you are having consistent issues with data loss, or unwanted record modification, then this collection of stored procedures may help you out With this set of scripts, you can:
• Capture trace information about a server, on a set schedule
• Filter the captured data to suit your needs
• Archive the data for future auditing
Trang 4This solution also allows the trace data to be stored in our central DBA repository
so you don't have scattered auditing information cluttering up your individual instances
Tracing stored procedures
The two stored procedures I present here offer a quick way to automatically enable customizable profiler traces on your SQL servers, as well as to centrally store trace information from any number of machines
The code for handling the trace data is slightly different between SQL 2000 and SQL 2005, but the overall functional logic is essentially the same in each case I provide both versions of the script in the code download for this book at http://www.simple‐talk.com/RedGateBooks/
RodneyLandrum/SQL_Server_Tacklebox_Code.zip
The first script, usp_startTrace, is shown in Listing 7.11 and is used to initiate the customizable trace This stored procedure handles all the tasks of setting up the tracing events, creating the trace file, setting up filters and starting the actual trace The script is set up to look at five different trace events, and these happen
to be the same default events that Profiler monitors, which are:
• Login Events
• Logout Events
• RPC Completion Events
• SQL Batch Completion Events
• SQL Batch Start Events
The script first looks to see if a trace with the name defined is already running This is done by querying the central data storage server This central storage is a linked server that has a database with the tables required to store and query this information Again, the script files to create this database on your linked server are included in the code download to this book
Once the trace name has been checked, the script sets up a trace that matches the parameters you have supplied This includes the ability to filter any of the trace event data columns with a keyword The most common filter use will be on the text data column, which holds the T-SQL code run by a user
Finally, the script stores the trace information in the central auditing database for future use
Trang 5USE [msdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
Procedure Name : usp_startTrace
-
Parameter 1 : traceName - Unique identifier of trace [Req] Parameter 2 : traceFile - Physical file to hold trace data while running [Req]
Parameter 3 : maxFileSize - Maximum size that traceFile can grow to [Default: 5MB]
Parameter 4 : filterColumn - Trace event data column to filter results on [Default: 0]
Parameter 5 : filterKeyword - Keyword used when filterColumn
is defined [Default: NULL]
*/
CREATE PROCEDURE [dbo].[usp_startTrace]
@traceName NVARCHAR(50),
@traceFile NVARCHAR(50),
@maxFileSize BIGINT 5,
@filterColumn INT 0,
@filterKeyword NVARCHAR(50) = NULL
AS
SET NOCOUNT ON
Test for trace existence in the Trace_IDs table, alert user if trace is invalid
Change linked server name here
IF EXISTS (
SELECT FROM MYSERVER123.DBA_Info.dbo.Trace_IDs
WHERE TraceName = @traceName OR TraceFile = @traceFile) AND TraceServer = SERVERPROPERTY ('ServerName')
)
BEGIN
PRINT('Trace ' @traceName + ' already exsists or the file is in use, please choose another name/file')
RETURN
END
/*
Variable Declaration
-
traceError - Will hold return code from sp_trace_create
to validate trace creation
TraceID - Will hold the system ID of the newly created trace