使用SQLServer Audit来监控触发器的启用、禁用情况(转载)
使用情景:
有时候会发现在触发器中的业务逻辑没有执行,可能是因为触发器的逻辑错误所引起的。但是有时候却是因为一些触发器被禁用了。
由于SQLServer默认不跟踪触发器的启用还是禁用。且禁用触发器的命令(Disable Trigger)不在默认跟踪里面捕获。但是可以在服务器级别的跟踪(不是使用Profiler)获取这些信息,捕获SQL:StmtCompleted并在TextData列筛选,但是对于负载较重的系统,这样会有比较大的影响。
如果你的是企业版,可以考虑使用一个新特性:SQL Server Audit。可以使用DATABASE AUDIT SPECIFICATION来捕获这些事件。
使用步骤:
第一步,使用以下语句先创建服务器级别监控:
- USE master;
- GO
- CREATE SERVER AUDIT ServerAudit
- TO FILE (FILEPATH = 'E:\temp\', MAXSIZE = 1 GB)--注意更改文件路径
- WITH (ON_FAILURE = CONTINUE);
- GO
- ALTER SERVER AUDIT ServerAudit
- WITH (STATE = ON);
USE master; GO CREATE SERVER AUDIT ServerAudit TO FILE (FILEPATH = 'E:\temp\', MAXSIZE = 1 GB)--注意更改文件路径 WITH (ON_FAILURE = CONTINUE); GO ALTER SERVER AUDIT ServerAudit WITH (STATE = ON);
注意,路径需要修改,temp文件夹也要实现开启。
第二步,创建数据库级别监控:
对于本文,我们关注SCHEMA_OBJECT_CHANGE_GROUP,以AdventureWorks为例子:
- USE AdventureWorks;
- GO
- CREATE DATABASE AUDIT SPECIFICATION schema_change
- FOR SERVER AUDIT ServerAudit
- ADD (SCHEMA_OBJECT_CHANGE_GROUP)
- WITH (STATE = ON);
- GO
USE AdventureWorks; GO CREATE DATABASE AUDIT SPECIFICATION schema_change FOR SERVER AUDIT ServerAudit ADD (SCHEMA_OBJECT_CHANGE_GROUP) WITH (STATE = ON); GO
第三步,创建一个示例表,然后创建一个示例触发器:
- CREATE TABLE dbo.splunge ( id INT ) ;
- GO
- CREATE TRIGGER dbo.splunge_trigger ON dbo.splunge
- FOR INSERT
- AS
- BEGIN
- SELECT 1 ;
- END
- GO
CREATE TABLE dbo.splunge ( id INT ) ; GO CREATE TRIGGER dbo.splunge_trigger ON dbo.splunge FOR INSERT AS BEGIN SELECT 1 ; END GO
第四步,可以使用以下脚本来检查:
- SELECT event_time ,
- succeeded ,
- server_principal_name ,
- [object_name] ,
- [statement]
- FROM sys.fn_get_audit_file('E:\Temp\ServerAudit*', NULL, NULL)
- WHERE database_name = 'AdventureWorks' ;
SELECT event_time , succeeded , server_principal_name , [object_name] , [statement] FROM sys.fn_get_audit_file('E:\Temp\ServerAudit*', NULL, NULL) WHERE database_name = 'AdventureWorks' ;
结果如下,可以看到捕获了创建的记录:
现在来禁用这个触发器,然后再查询一下:
- DISABLE TRIGGER dbo.splunge_trigger ON dbo.splunge;
- GO
- SELECT event_time ,
- succeeded ,
- server_principal_name ,
- [object_name] ,
- [statement]
- FROM sys.fn_get_audit_file('E:\Temp\ServerAudit*', NULL, NULL)
- WHERE database_name = 'AdventureWorks' ;
DISABLE TRIGGER dbo.splunge_trigger ON dbo.splunge; GO SELECT event_time , succeeded , server_principal_name , [object_name] , [statement] FROM sys.fn_get_audit_file('E:\Temp\ServerAudit*', NULL, NULL) WHERE database_name = 'AdventureWorks' ;
结果如下:
如果你重新启用这个触发器,你会再看到另外一行,如果觉得返回数据太多,可以在where语句中添加筛选:
- AND [statement] LIKE '%disable%trigger%'
AND [statement] LIKE '%disable%trigger%'
但是有时候会存在误报,比如,在你的代码里面可能存在同样的信息。但是筛选数据对性能和检查问题总是有好处的。
小结:
捕获事件有很多种方式。此功能仅限2008企业版使用。
分类:
mssql
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
2011-12-05 使用NEWSEQUENTIALID解决GUID聚集索引问题