SQL Server架构审计?

时间:2012-07-13 12:14:26

标签: sql database sql-server-2008 database-administration ddl-trigger

我们有一个SQL Server 2008 Enterprise数据库,它有两个不同的模式,一个我们维护的锁定模式和一个我们允许外部开发团队根据自己的需要添加和修改的开放模式。通常这对我们来说没问题,但是一个特定的团队喜欢真正搞砸它并且它正在影响其他所有人。所以有2个问题:

  1. 事后我希望我们从一开始就设置了一些强大的东西,但我们没有,只是默认安装。能够看到到目前为止已经对模式做了什么将是很好的,即使它的简单如用户XYZ在2012年12月7日上午9点更改了过程ABC'。是否有任何内置于SQL Server中并且默认情况下启用了跟踪我们可能利用的内容,如果是,那么在哪里/如何?
  2. 就长期解决方案而言,您会为此推荐什么?我已经阅读了一些DDL触发器,这似乎是一个很有前景的选择。如果您已经使用过这种方法,那么您可以分享它的工作方式以及使用它可以做些什么吗?
  3. 谢谢

4 个答案:

答案 0 :(得分:4)

我有一个使用DDL触发器的系统就是这种类型的东西。它足以满足我的需求。它最初是在Sql Server 2005上开发的,现在位于Sql Server 2008R2系统上。它类似于Aaron Bertrand评论中链接所描述的那个。

创建一个与此类似的表。

CREATE TABLE [dbo].[SchemaLog](
    [SchemaLogID] [int] IDENTITY(1,1) NOT NULL,
    [PostTimeUtc] [datetime] NOT NULL,
    [DatabaseUser] [nvarchar](128) NOT NULL,
    [Event] [nvarchar](128) NOT NULL,
    [Schema] [nvarchar](128) NULL,
    [Object] [nvarchar](128) NULL,
    [TSQL] [nvarchar](max) NOT NULL,
    [XmlEvent] [xml] NOT NULL,
 CONSTRAINT [PK_SchemaLog_1] PRIMARY KEY CLUSTERED 
(
    [SchemaLogID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

确保每个人都对表有插入权限,然后创建一个类似于此的ddl触发器。

CREATE TRIGGER [ddlDatabaseTriggerLog] ON DATABASE  FOR DDL_DATABASE_LEVEL_EVENTS AS  
BEGIN     
    SET NOCOUNT ON;     
    DECLARE @data XML;     
    DECLARE @schema sysname;     
    DECLARE @object sysname;     
    DECLARE @eventType sysname;     
    SET @data = EVENTDATA();     
    SET @eventType = @data.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname');     
    SET @schema = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname');     
    SET @object = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname')      
    IF @object IS NOT NULL         
        PRINT '  ' + @eventType + ' - ' + @schema + '.' + @object;     
    ELSE         
        PRINT '  ' + @eventType + ' - ' + @schema;     

    IF @eventType IS NULL         
        PRINT CONVERT(nvarchar(max), @data);     

    INSERT [dbo].[SchemaLog]          (         
        [PostTimeUtc]
    ,          [DatabaseUser]
    ,          [Event]
    ,          [Schema]
    ,          [Object]
    ,          [TSQL]
    ,          [XmlEvent]         )      
    VALUES          (         
        GETUTCDATE()
    ,          CONVERT(sysname, CURRENT_USER)
    ,          @eventType
    ,          CONVERT(sysname, @schema)
    ,          CONVERT(sysname, @object)
    ,          @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)')
    ,          @data         ); 

END;

查看以按顺序选择更改

create view SchemaLogOrdered
as
SELECT top 10000 *
FROM            dbo.SchemaLog
ORDER BY  SchemaLogID DESC

答案 1 :(得分:1)

Redgate选项如下。

1)开始审核架构更改的最简单方法是安装DLM Dashboard。这是一个免费工具,可使用DDL触发器提醒和记录所有更改,并包含您要求的信息。

2)正如Andy Davies已经提到的,正确的方法是以与应用程序代码相同的方式启动源代码控制。完成此操作后,您可以通过将数据库包含在持续集成和发布管理实践中来提高database lifecycle management的成熟度。

答案 2 :(得分:0)

您可以将数据库置于源代码管理之下。也许让每个外部团队都采用数据库的分支或分支。这使您可以通过提交审核更改,并能够在合并之前选择要合并的更改和/或查看/编辑这些更改。

查看http://www.red-gate.com/products/sql-development/sql-source-control/一个可用的产品。

与Github或Bitbucket等解决方案相结合,可以通过互联网更直接地向外部贡献者开放源代码管理存储库。

答案 3 :(得分:0)

对于第二个问题,您可以将触发器视为一种选择。在以下示例中,使用SQL Server的EVENTDATA()函数捕获有关触发触发器的事件的信息。 SQL脚本创建DDL触发器,捕获数据库级别上的CREATE,ALTER和DROP事件(尽管可以在服务器级别创建触发器以捕获服务器上所有数据库的事件;应使用ON ALL SERVER选项,而不是ON DATABASE)

CREATE TRIGGER Audit_DDL ON DATABASE
FOR CREATE_TABLE , ALTER_TABLE , DROP_TABLE
AS
DECLARE
@event xml;
SET @event = EVENTDATA(
                  );
INSERT INTO Audit_DDL_Events
VALUES( REPLACE( CONVERT( varchar( 50
                             ) , @event.query( 'data(/EVENT_INSTANCE/PostTime)'
                                             )
                    ) , 'T' , ' '
           ) , 
    CONVERT( varchar( 150
                    ) , @event.query( 'data(/EVENT_INSTANCE/LoginName)'
                                    )
           ) , 
    CONVERT( varchar( 150
                    ) , @event.query( 'data(/EVENT_INSTANCE/UserName)'
                                    )
           ) , 
    CONVERT( varchar( 150
                    ) , @event.query( 'data(/EVENT_INSTANCE/DatabaseName)'
                                    )
           ) , 
    CONVERT( varchar( 150
                    ) , @event.query( 'data(/EVENT_INSTANCE/SchemaName)'
                                    )
           ) , 
    CONVERT( varchar( 150
                    ) , @event.query( 'data(/EVENT_INSTANCE/ObjectName)'
                                    )
           ) , 
    CONVERT( varchar( 150
                    ) , @event.query( 'data(/EVENT_INSTANCE/ObjectType)'
                                    )
           ) , 
    CONVERT( varchar( max
                    ) , @event.query( 'data(/EVENT_INSTANCE/TSQLCommand/CommandText)'
                                    )
           )
  );

还必须创建适用于EVENTDATA XML审核数据的存储表:

CREATE TABLE Audit_DDL_Events( DDL_Event_Time datetime , 
                           DDL_Login_Name varchar( 150
                                                 ) , 
                           DDL_User_Name varchar( 150
                                                ) , 
                           DDL_Database_Name varchar( 150
                                                    ) , 
                           DDL_Schema_Name varchar( 150
                                                  ) , 
                           DDL_Object_Name varchar( 150
                                                  ) , 
                           DDL_Object_Type varchar( 150
                                                  ) , 
                           DDL_Command varchar( max
                                              )
                         );