SQL Server备份不触发DML或DDL触发器,因其是引擎级I/O操作,绕过查询优化器和用户表修改;需改用msdb.backupset轮询、DMV监控及错误日志分析组合方案识别中断。

不能直接用触发器监控备份中断。SQL Server 的 BACKUP 操作本身不触发 DML 事件,INSERTED/DELETED 临时表对它完全不可见,所以传统 DML 触发器(AFTER INSERT、INSTEAD OF UPDATE 等)在这里无效。
为什么 backup 不走触发器路径
备份是数据库引擎级的 I/O 操作,绕过查询优化器和事务日志的常规写入流程,也不修改用户表数据。触发器只响应 INSERT、UPDATE、DELETE、MERGE 这类 DML 语句,而 BACKUP DATABASE 属于 DDL+管理命令,压根不会激活任何用户定义的触发器。
常见误判现象:
- 在 msdb..backupset 表上建了 AFTER INSERT 触发器,结果备份失败时没触发
- 以为在 sys.dm_exec_sessions 或 sys.dm_exec_requests 上轮询就能捕获“中断”,但这些 DMV 只反映当前状态,不记录历史失败原因
替代方案:用 SQL Agent + msdb 状态轮询 + 自定义日志表
真正可行的做法是放弃触发器,转而利用 msdb 中已有的备份元数据,配合作业调度做主动检查:
- SQL Server 每次执行
BACKUP(无论成功或失败),都会往msdb.dbo.backupset插入一条记录,其中is_checkpoint_torn、has_backup_checksums字段不可靠,但backup_finish_date为空 +type = 'D'(全备)或'I'(差异)+server_name匹配,基本可判定为异常中断 - 新建一张监控表
dbo.backup_interruption_log,字段至少包含:backup_set_id、database_name、start_date、finish_date、error_message、check_time - 用 SQL Agent 创建一个每 5 分钟执行一次的作业,运行如下逻辑:
INSERT INTO dbo.backup_interruption_log
SELECT
bs.backup_set_id,
bs.database_name,
bs.backup_start_date,
bs.backup_finish_date,
'No finish time, likely interrupted' AS error_message,
GETDATE() AS check_time
FROM msdb.dbo.backupset bs
WHERE bs.backup_finish_date IS NULL
AND bs.backup_start_date > DATEADD(minute, -10, GETDATE())
AND bs.type IN ('D', 'I', 'L');注意:backup_finish_date IS NULL 并非绝对等于“中断”——极少数正常备份可能因日志截断延迟导致短暂为空,所以加了 backup_start_date > DATEADD(minute, -10, GETDATE()) 时间窗过滤,避免误报。
更准的判断:结合 sys.dm_exec_requests 和错误日志
如果需要更高精度(比如区分“卡住”和“被 KILL”),得组合多个信号源:
- 查
sys.dm_exec_requests中状态为running且command LIKE '%BACKUP%',但start_time超过 30 分钟未更新last_request_end_time,说明可能挂起 - 用
EXEC sp_readerrorlog 0, 1, 'backup'扫描当前错误日志,匹配关键词如'aborted'、'failed'、'interrupted'、'KILLED' - 把这两路结果都写入
backup_interruption_log,并标记来源类型('msdb_null_finish'/'dm_exec_hang'/'errorlog_keyword')
不要依赖单一条件。真实生产环境里,“备份中断”可能是磁盘满、权限丢失、网络闪断、TDE 密钥不可用等多种原因导致,它们在不同层面留下痕迹——msdb 记录缺失、DMV 显示阻塞、错误日志输出具体报错。只盯一个点,大概率漏掉关键线索。
最常被忽略的一点:SQL Agent 作业本身必须启用“写入 Windows 应用程序日志”,否则你连轮询脚本是否成功执行都难确认;另外,msdb.dbo.backupset 表默认只保留 7 天历史,需定期归档或调大 sp_delete_backuphistory 的清理阈值,否则中断记录很快被删光。

















