首页 > 代码库 > 监控数据库DDL操作日志

监控数据库DDL操作日志

背景

为了监控好生产环境下各个数据库服务器上DDL操作日志,便于运维工程师管控好风险,我们有必要关注当前实例下的所有的DDL操作。

测试环境

Microsoft SQL Server 2012 - 11.0.2218.0 (X64) 
Jun 12 2012 13:05:25 
Copyright (c) Microsoft Corporation
Developer Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: )

操作步骤

第一步.在监控库中新建DDL监控表用来存放DDL监控日志记录
1 --新建监控库,如果已存在该数据库,可以不执行
2 USE master;
3 IF DB_ID(azure_monitor) IS NOT NULL
4     DROP DATABASE azure_monitor;
 1 CREATE DATABASE azure_monitor
 2 ON
 3 --请根据实际情况选择监控库的存放路径
 4 (   NAME = azure_monitor,
 5     FILENAME = d:\azure_monitor.mdf,
 6     FILEGROWTH = 50MB
 7 )
 8 LOG ON
 9 (   NAME = azure_monitor_log,
10     FILENAME = d:\azure_monitore_log.ldf,
11     FILEGROWTH = 50MB
12 );
1 USE master;
2 ALTER DATABASE azure_monitor SET RECOVERY SIMPLE;
 1 USE [azure_monitor];
 2 CREATE TABLE [dbo].[monitor_DatabaseLog]
 3 (
 4     [DatabaseLogID] [INT] IDENTITY(1, 1) NOT NULL,
 5     [PostTime] [DATETIME] NOT NULL,
 6     [DatabaseUser] [sysname] NOT NULL,
 7     [LoginName] [sysname] NOT NULL,
 8     [Event] [sysname] NOT NULL,
 9     [databasename] [sysname] NULL,
10     [Schema] [sysname] NULL,
11     [Object] [sysname] NULL,
12     [TSQL] [NVARCHAR](MAX) NOT NULL,
13     [XmlEvent] [XML] NOT NULL,
14     CONSTRAINT [PK_DatabaseLog_DatabaseLogID]
15         PRIMARY KEY NONCLUSTERED ([DatabaseLogID] ASC)
16         WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
17                  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
18                  ALLOW_PAGE_LOCKS = ON
19              ) ON [PRIMARY]
20 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY];
21 GO
第二步.新建实例级别的触发器
 1 CREATE TRIGGER [ddlDatabaseTriggerLog]
 2 ON ALL SERVER
 3 WITH EXECUTE AS sa  ---根据实际情况选择
 4 FOR DDL_DATABASE_LEVEL_EVENTS, CREATE_DATABASE, DROP_DATABASE, ALTER_DATABASE, CREATE_LOGIN
 5 AS
 6 BEGIN
 7     SET NOCOUNT ON;
 8     DECLARE @data XML;
 9     DECLARE @LoginName sysname;
10     DECLARE @databasename sysname;
11     DECLARE @schema sysname;
12     DECLARE @object sysname;
13     DECLARE @eventType sysname;
14     SET @data = EVENTDATA();
15     SET @LoginName
16         = @data.value((/EVENT_INSTANCE/LoginName)[1], sysname);
17     SET @databasename
18         = @data.value((/EVENT_INSTANCE/DatabaseName)[1], sysname);
19     SET @eventType
20         = @data.value((/EVENT_INSTANCE/EventType)[1], sysname);
21     SET @schema = @data.value((/EVENT_INSTANCE/SchemaName)[1], sysname);
22     SET @object = @data.value((/EVENT_INSTANCE/ObjectName)[1], sysname);
23     IF @object IS NOT NULL
24         PRINT    + @eventType +  -  + @databasename + . + @schema + .
25               + @object;
26     ELSE
27         PRINT    + @eventType +  -  + @databasename + . + @schema;
28     IF @eventType IS NULL
29         PRINT CONVERT(NVARCHAR(MAX), @data);
30     ---写入的日志记录对应的库名是否正确
31     INSERT [azure_monitor].[dbo].[monitor_DatabaseLog]
32     (   [PostTime],
33         [DatabaseUser],
34         [LoginName],
35         [Event],
36         [databasename],
37         [Schema],
38         [Object],
39         [TSQL],
40         [XmlEvent]
41     )
42     VALUES
43     (   GETDATE(),
44         CONVERT(sysname, CURRENT_USER),
45         CONVERT(sysname, @LoginName),
46         @eventType,
47         CONVERT(sysname, @databasename),
48         CONVERT(sysname, @schema),
49         CONVERT(sysname, @object),
50         @data.value((/EVENT_INSTANCE/TSQLCommand)[1], nvarchar(max)),
51         @data
52     );
53 END;
54 GO

监控效果

技术分享

后记

  1. 所有的人员登陆都已提前开设好各自的登陆用户;
  2. 严格隔离区分不同的人员之间操作权限;
 

参考

create trigger

 

监控数据库DDL操作日志