发生任何RESTORE DATABASE事件后自动执行存储过程


9

是否有可能让SQL Server 2008 R2 Standard还原附加到实例的任何给定数据库中自动执行存储过程?

我已经通过创建服务器级触发器来解决一个问题,该触发器将在DDL事件发生CREATE_DATABASEALTER_DATABASE触发后在给定的数据库中执行存储过程。不幸的是,这不适用于数据备份备份还原。

详细地说,我们在还原的每个数据库中都有一个“清理”存储过程,我正在寻找一种方法,可以在将备份还原到实例时自动执行该过程。

Googling向我指出了要在SQL Server中配置“ 审计”或“ 策略”以获得此功能,但是乍一看,这些功能非常强大,因此我无法确定审计还是“警察”是开始调查的途径。

Answers:


10

还原完成后是否必须立即执行,还是可以短暂延迟?我想到的一个想法是,每分钟运行一次作业,并检查Audit Backup/Restore Event默认跟踪中的。

DECLARE @fn VARCHAR(MAX);

SELECT @fn = SUBSTRING([path], 0, LEN([path])-CHARINDEX(CHAR(92), REVERSE([path]))+1) 
  + CHAR(92) + 'Log.trc'  
FROM sys.traces   
WHERE is_default = 1;  

SELECT 
    DatabaseName,
    StartTime, 
    TextData
FROM sys.fn_trace_gettable(@fn, DEFAULT)  
WHERE EventClass = 115
AND TextData LIKE '%RESTORE%'; -- since can't differentiate between backup/restore

您可以存储已经基于StartTime完成的清理,甚至可以限制每分钟运行的跟踪查询(或您可以接受的延迟阈值),以便仅查看大于您提取的最后一行或最后一行的StartTime值工作运行的时间,以较少者为准。


1
非常光滑,善于思考。+1
Thomas Stringer '04年

稍微延迟是可以接受的。我要尝试一下。
马修·鲁斯顿

1
请注意,我尚未确认在所有情况下事件在写入跟踪行之前实际上已经完成。我怀疑这是事后写的,但我只是因为EndTime似乎从未有人居住而感到怀疑。在某些情况下,您应该尝试连接到数据库,如果无法连接,请跳过它并且不记录此还原事件,但是在下次作业运行时重试。我会尝试进行验证,但在本地VM上我只有SSD,但它们没有足够的磁盘空间来使备份花费足够长的时间才能准确观察到行为。:-)
亚伦·伯特兰

6

database_started 扩展事件还原数据库之后被激发。

创建一个事件会话,database_id使用%RESTORE%在该sql_text字段中查找的谓词捕获该字段(请注意:我相信这已经足够了,您需要自己进行测试)。

我对扩展事件还不够熟悉,无法告诉您如何响应事件的最佳方法。如果您可以直接触发存储过程,那就太好了;不过,我不知道是否有可能。但是,您当然可以轮询事件缓冲区,这比扫描默认跟踪更好-不仅是出于性能方面的考虑,而且如果服务器非常繁忙且轮询间隔太长,最终可能会丢失所有事件。使用扩展事件方法,丢失事件的可能性很小。


4

DDL事件列表中可以看到,DDL触发器不能足够明确地满足您的要求。

我建议编写PowerShell脚本进行还原或附加,然后紧接着执行存储过程。请注意,必须指示您的商店使用它,而不是典型的还原或附加。

不幸的是,我不相信有内置的方法可以完成此任务。


4

您如何运行备份?如果您只是想在备份后运行SP,则可以将其设置为作业中的另一个任务(如果正在使用它们)或维护计划。

因此,您可以设置“审核”以写入事件日志,然后创建将执行作业的警报。似乎令人费解,但是它将满足您的要求。

看下面的代码:

--Create the Server Audit
USE master
GO
CREATE SERVER AUDIT BackupTrap
TO APPLICATION_LOG
WITH (QUEUE_DELAY = 0, ON_FAILURE = CONTINUE)
GO

--Turn the Audit On
ALTER SERVER AUDIT BackupTrap
WITH (STATE = ON)
GO

--Create the Database Audit Specification
USE AdventureWorks2012
GO
CREATE DATABASE AUDIT SPECIFICATION BackupTrapAdventureWorks
FOR SERVER AUDIT BackupTrap
    ADD (BACKUP_RESTORE_GROUP)
WITH (STATE = ON)
GO

--Create the job to run
USE msdb
GO
EXECUTE dbo.sp_add_job
    @job_name = N'BackupAlertJob'
GO

EXECUTE dbo.sp_add_jobserver
    @job_name = N'BackupAlertJob'
GO

EXECUTE dbo.sp_add_jobstep
    @job_name = N'BackupAlertJob',
    @step_name = N'RunSP',
    @subsystem = N'TSQL',
    @command = N'EXECUTE dbo.MyStoredProcedure',
    @database_name = N'AdventureWorks2012'
GO

捕获到这一点的还原作业是一个好主意。但是,我不知道这是否是一个完整的解决方案,因为OP希望捕获“任何”还原事件。
Nick Chammas 2012年

我们真正追求的是在任何还原事件完成之后能够执行任意存储过程。尽管如此,这是一个有效的建议。
马修·鲁斯顿

我删除了第二个答案,并编辑以上内容以包含信息。感谢@Shark提供有关该提示的技巧。完全没有考虑这样做。
jgardner04

0

您如何运行备份?使用Commvault,您可以设置自动还原作业,并使其运行SQL或Powershell之前和之后的还原脚本。我一直在这样做,以运行DDL来解决版本差异以及在环境之间进行还原时备份和还原权限。

我相信Netbackup可以使其他产品具有类似的功能

如果您使用SQL,只需将其添加为还原数据库的步骤即可

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.