Saturday, 1 December 2012

Database level Audit for DDL changes


One of the application team came with a requirement that they don't have a control of who is modifying the schema level changes as the development team have full access in development environment. After discussion, we thought of enabling an audit which traps the necessary information in a table. That can be provided as a report to the application team when needed.I just tried this and it worked fine.

Steps followed:

1. Create a DDL trigger on the datbase which needs to track the schema changes.
2. Create a table on the database which is used by DBA for auditing.
3. Insert that values into the audit table.
4. The table will have data viz Event time, event type, object name, object type, login name, command text and Host Name.
5. So whenever there is a schema change all the above information will be captured and inserted into a different DB which is owned by the DBA team.

Setup:

Creation of trigger in the AppDB:


USE [Appdb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [trg_DBEvents]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
BEGIN
      SET NOCOUNT ON

      DECLARE @xmlEventData XML
      DECLARE @hostname NVARCHAR(100)
      SET @xmlEventData = eventdata()
      SET @hostname = HOST_NAME()
      INSERT INTO AuditDb.dbo.DDL_Event_log([EventTime], [EventType],
[ObjectName], [ObjectType],[LoginName],
       [CommandText],[HostIP])
      SELECT REPLACE(CONVERT(VARCHAR(50), @xmlEventData.query('data(/EVENT_INSTANCE/PostTime)')),'T', ' '),
            CONVERT(VARCHAR(100), @xmlEventData.query('data(/EVENT_INSTANCE/EventType)')),
CONVERT(VARCHAR(100),
@xmlEventData.query('data(/EVENT_INSTANCE/ObjectName)')),
            CONVERT(VARCHAR(100), @xmlEventData.query('data(/EVENT_INSTANCE/ObjectType)')),
            CONVERT(VARCHAR(100), @xmlEventData.query('data(/EVENT_INSTANCE/LoginName)')),
            CONVERT(VARCHAR(MAX), @xmlEventData.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)')),
            @hostname
           
END


Creation of table in the AuditDB : 


USE [AuditDb]
GO

CREATE TABLE [dbo].[DDL_Event_log](
      [EventID] [int] IDENTITY(1,1) NOT NULL,
      [EventTime] [varchar](100) NULL,
      [EventType] [varchar](100) NULL,
      [ObjectName] [varchar](100) NULL,
      [ObjectType] [varchar](100) NULL,
      [LoginName] [varchar](100) NULL,
      [CommandText] [varchar](max) NULL,
      [HostIP] [varchar](50) NULL,
 CONSTRAINT [PK_DDL_Event_log] PRIMARY KEY CLUSTERED
(
      [EventID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [Secondary]
) ON [Secondary]

GO



Check how it works :


I am going to create a new stored procedure in AppDB database logging in as sql user.


USE [Appdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[new_dummy_proc]
     
AS
BEGIN

SELECT * from dbo.inventorydetails where inventoryid is not null;
     
END

When we see the log table created under the AuditDB database the changes has been captured.







Now I will alter the same procedure with a windows user and see the log table.









Security:

When a new user is created, DBA needs to be provide write access to the AuditDB to capture the ddl changes.

Note:Though creating trigger impact performance, it is accepted as the setup is easy and it is implemented on non-production environment.

Saturday, 3 November 2012

SQL Server Vs Oracle - terminology difference


This Thursday, while I was having a discussion with team on change the current SQL architecture, one management guy from Oracle background was suggesting to group all the schema with a common name based on the business logic.

It took a while for me to understand that why he wants to keep all the schema from different database to have it in a single name, instead we can keep in the same database and put it in a different instance. Later we understood that as both are talking on different technology the technical terms varies.

Based on that, I thought of writing the terminology difference between both SQL Server and Oracle.



Monday, 29 October 2012

Consider - while creating a new SQL Server database


1. Do not keep data or log files on the drive where OS is installed.


2. Keep the data file (.mdf and .ndf) and log file in seperate drive.


3. Keep the growth size of both data and log file in megabytes not in percent.


4. Set the maximum file size growth don't set is as unrestricted file growth.


5. Create a secondary filegroup and make it as default.


6. Create a secondary file (.ndf) to store the data


7. It is recommended to create (.ndf) one new file for each module.


8. Set the recovery model as full (prod env).


9. Set the Auto update statistics = True.


10. Set the page verify = CHECKSUM