Gespeicherte Prozedur nach jedem RESTORE DATABASE-Ereignis automatisch ausführen

9

Ist es möglich, dass SQL Server 2008 R2 Standard automatisch eine gespeicherte Prozedur in einer bestimmten Datenbank ausführt , die wiederhergestellt oder an die Instanz angehängt wird ?

Ich bin einer Lösung nahe gekommen, indem ich einen Trigger auf Serverebene erstellt habe, der eine gespeicherte Prozedur in einer bestimmten Datenbank nach dem DDL-Ereignis ausführt CREATE_DATABASEoder ALTER_DATABASEausgelöst wird. Leider funktioniert dies nicht für Datenback-Backup-Wiederherstellungen.

Um dies zu erläutern, haben wir eine gespeicherte Prozedur zum Bereinigen, die in jeder Datenbank vorhanden ist, die wir wiederherstellen, und ich suche nach einer Möglichkeit, diese automatisch auszuführen, wenn eine Sicherung in der Instanz wiederhergestellt wird.

Googeln hat mich darauf hingewiesen, entweder Audits oder Richtlinien in SQL Server zu konfigurieren , um diese Funktionalität zu erhalten, aber diese Funktionen sind auf den ersten Blick ziemlich überwältigend, sodass ich nicht sagen kann, ob Audits oder Richtlinien der Weg sind, um mit der Untersuchung zu beginnen.

Matthew Ruston
quelle

Antworten:

10

Muss es sofort nach Abschluss der Wiederherstellung ausgeführt werden oder kann es kurz verzögert werden? Eine Idee, die ich hatte, war, einen Job zu haben, der jede Minute ausgeführt wird und Audit Backup/Restore Eventim Standard-Trace nach dem sucht.

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

Sie können die Bereinigungen, die Sie bereits basierend auf StartTime durchgeführt haben, speichern und sogar die Ablaufverfolgungsabfrage, die jede Minute ausgeführt wird (oder was auch immer Ihr akzeptabler Verzögerungsschwellenwert ist), so einschränken, dass nur StartTime-Werte angezeigt werden, die größer sind als die letzte Zeile, die Sie gezogen haben, oder die letzte Zeit, in der der Job ausgeführt wurde, je nachdem, welcher Wert geringer ist.

Aaron Bertrand
quelle
1
Sehr schlau, gut denkend. +1
Thomas Stringer
Eine leichte Verzögerung wäre akzeptabel. Ich werde das ausprobieren.
Matthew Ruston
1
Beachten Sie, dass ich nicht bestätigt habe, dass das Ereignis in allen Fällen tatsächlich beendet ist, bevor die Ablaufverfolgungszeile geschrieben wird. Ich vermute, dass es sich um ein Post-Event-Schreiben handelt, aber ich bin nur misstrauisch, weil es EndTimenie bevölkert zu sein scheint. Möglicherweise sollten Sie versuchen, eine Verbindung zur Datenbank herzustellen. Wenn dies nicht möglich ist, überspringen Sie diese und dokumentieren Sie dieses Wiederherstellungsereignis nicht. Versuchen Sie es jedoch erneut, wenn der Job das nächste Mal ausgeführt wird. Ich würde versuchen, zu validieren, aber auf meinen lokalen VMs habe ich nur SSDs, aber sie haben nicht den Speicherplatz, damit eine Sicherung lange genug dauert, um das Verhalten genau zu beobachten. :-)
Aaron Bertrand
6

Das database_started erweiterte Ereignis wird ausgelöst, nachdem eine Datenbank wiederhergestellt wurde.

Erstellen Sie eine Ereignissitzung, die das database_idFeld mit einem Prädikat erfasst , nach dem %RESTORE%im sql_textFeld gesucht wird (Hinweis: Ich glaube, dies ist ausreichend - Sie möchten es selbst testen).

Ich bin mit erweiterten Ereignissen nicht vertraut genug, um Ihnen zu sagen, wie Sie am besten auf das Ereignis reagieren können. Es wäre schön, wenn Sie eine gespeicherte Prozedur direkt auslösen könnten. Ich weiß allerdings nicht, ob das möglich ist. Sie können den Ereignispuffer jedoch auf jeden Fall abfragen. Dies ist dem Scannen der Standardablaufverfolgung vorzuziehen - nicht nur aus Leistungsgründen. Wenn der Server sehr ausgelastet ist und das Abfrageintervall zu lang ist, können Ereignisse sofort fehlen. Mit der Extended Events-Methode ist es sehr unwahrscheinlich, dass ein Ereignis fehlt.

Jon Seigel
quelle
4

Wie Sie der Liste der DDL-Ereignisse entnehmen können , kann ein DDL-Trigger für Ihre Anforderung nicht explizit genug sein.

Ich würde empfehlen, ein PowerShell- Skript zu schreiben , um die Wiederherstellung oder das Anhängen durchzuführen und dann die gespeicherte Prozedur unmittelbar danach auszuführen. Wohlgemerkt, Ihr Shop muss angewiesen werden, dies anstelle einer typischen Wiederherstellung oder eines Anhängens zu verwenden.

Leider glaube ich nicht, dass es einen eingebauten Weg gibt, dies zu erreichen.

Thomas Stringer
quelle
4

Wie führen Sie Ihre Backups aus? Wenn Sie den SP nur nach Ihrer Sicherung ausführen möchten, können Sie ihn als eine andere Aufgabe im Job einrichten, wenn Sie sie verwenden, oder als Wartungsplan.

So können Sie die Überwachung so einrichten, dass sie in das Ereignisprotokoll schreibt und anschließend eine Warnung erstellt, die einen Job ausführt. Es scheint verworren zu sein, aber es wird tun, was Sie verlangen.

Sehen Sie sich den folgenden Code an:

--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
quelle
Ein Wiederherstellungsjob, der dies erfasst, ist eine gute Idee. Ich frage mich jedoch, ob dies eine vollständige Lösung ist, da das OP "jedes" Wiederherstellungsereignis erfassen möchte.
Nick Chammas
Die Möglichkeit, eine beliebige gespeicherte Prozedur nach Abschluss eines Wiederherstellungsereignisses auszuführen, ist genau das, wonach wir suchen. Trotzdem ein gültiger Vorschlag.
Matthew Ruston
Ich habe meine zweite Antwort entfernt und die oben genannten bearbeitet, um die Informationen aufzunehmen. Danke @Shark für den Tipp dazu. Ich habe überhaupt nicht daran gedacht.
jgardner04
0

Wie führen Sie Ihre Backups aus? Mit Commvault können Sie einen automatischen Wiederherstellungsjob einrichten und vor und nach der Wiederherstellung Skripts ausführen lassen, die SQL oder Powershell sein können. Ich mache dies die ganze Zeit, um DDL für Versionsunterschiede auszuführen und Berechtigungen beim Wiederherstellen zwischen Umgebungen zu sichern und wiederherzustellen.

Ich glaube, Netbackup kann andere Produkte ähnliche Funktionen haben

Wenn Sie SQL verwenden, fügen Sie es einfach als Schritt zum Job hinzu, der die Datenbank wiederherstellt

Alen
quelle