Автоматически выполнять хранимую процедуру после любого события RESTORE DATABASE

9

Возможно ли, чтобы SQL Server 2008 R2 Standard автоматически выполнял хранимую процедуру в любой заданной базе данных, которая была восстановлена или присоединена к экземпляру?

Я приблизился к решению, создав триггер уровня сервера, который выполняет хранимую процедуру в данной базе данных после события DDL CREATE_DATABASEили ALTER_DATABASEзапускается. К сожалению, это не работает для восстановления резервных копий базы данных.

Чтобы уточнить, у нас есть хранимая процедура «очистки», которая существует в каждой восстанавливаемой базе данных, и я ищу способ, чтобы она выполнялась автоматически всякий раз, когда резервная копия восстанавливается в экземпляре.

Googling указал мне на настройку Аудитов или Политик в SQL Server, чтобы получить эту функциональность, но на первый взгляд эти функции являются довольно подавляющими, поэтому я не могу сказать, являются ли Аудиты или Политики подходом для начала расследования.

Мэтью Растон
источник

Ответы:

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
Томас Стрингер
Небольшая задержка будет приемлемой. Я собираюсь попробовать это.
Мэтью Растон
1
Обратите внимание, что я не подтвердил, что во всех случаях событие фактически завершается до записи строки трассировки. Я подозреваю, что это пост-событие, но я подозрительна только потому, что EndTimeникогда не кажется, что он заполнен. Возможно, вам следует попытаться подключиться к базе данных и, если вы не можете, пропустить ее и не задокументировать это событие восстановления, но повторите попытку при следующем запуске задания. Я бы попробовал проверить, но на моих локальных виртуальных машинах у меня есть только твердотельные накопители, но у них нет места на диске, чтобы резервное копирование занимало достаточно много времени для точного наблюдения за поведением. :-)
Аарон Бертран
6

database_started Расширенная Событие вызывается после восстановления базы данных.

Создайте сеанс событий, который захватывает database_id поле с предикатом, который ищет %RESTORE%в sql_textполе (примечание: я считаю, что этого достаточно - вы захотите проверить себя).

Я недостаточно знаком с Расширенными событиями, чтобы рассказать вам, как лучше всего реагировать на событие. Было бы хорошо, если бы вы могли запустить хранимую процедуру напрямую; Я не знаю, возможно ли это, хотя. Однако вы, безусловно, можете опрашивать буфер событий, и это предпочтительнее, чем сканирование трассировки по умолчанию - не только по соображениям производительности, но если сервер очень занят и интервал опроса слишком велик, вы можете в конечном итоге пропустить пропущенные события. При использовании метода расширенных событий пропустить событие было бы очень маловероятным.

Джон Сайгель
источник
4

Как вы можете видеть по списка событий DDL, триггер DDL не может быть достаточно явным для вашего требования.

Я бы порекомендовал написать сценарий PowerShell, чтобы выполнить восстановление или присоединение, а затем сразу выполнить хранимую процедуру. Имейте в виду, ваш магазин должен быть проинструктирован использовать это вместо типичного восстановления или прикрепления.

К сожалению, я не верю, что есть встроенный способ сделать это.

Томас Стрингер
источник
4

Как у вас дела с резервными копиями? Если вы просто хотите запустить SP после резервного копирования, вы можете установить его в качестве другой задачи в задании, если вы его используете, или в плане обслуживания.

Таким образом, вы можете настроить Auditing для записи в журнал событий, а затем создать предупреждение, которое будет выполнять задание. Это кажется запутанным, но он сделает то, что вы просите.

Взгляните на следующий код:

--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
jgardner04
источник
Задание восстановления, которое фиксирует это, является хорошей идеей. Тем не менее, мне интересно, является ли это полным решением, учитывая, что ОП хочет зафиксировать «любое» событие восстановления.
Ник Чаммас
Возможность выполнить произвольную хранимую процедуру после завершения любого события восстановления - это действительно то, что нам нужно. Действительное предложение тем не менее.
Мэтью Растон
Я удалил свой второй ответ и отредактировал вышеупомянутое, чтобы включить информацию. Спасибо @Shark за подсказку. Совершенно не думал об этом.
jgardner04
0

Как у вас дела с резервными копиями? С Commvault вы можете настроить автоматическое задание восстановления и запустить его до и после сценариев восстановления, которые могут быть SQL или powershell. Я делаю это все время для запуска DDL для различий версий и для резервного копирования и восстановления разрешений при восстановлении между средами.

Я считаю, что Netbackup может иметь другие продукты с похожей функциональностью

Если вы используете SQL, просто добавьте его в качестве шага к работе, которая восстанавливает базу данных

Alen
источник