Wie stelle ich einen Stapel von Transaktionsprotokollen statt einzeln wieder her?

11

Ich habe eine SQL Server-Datenbank, die alle 10 Minuten die Transaktionsprotokolle mit einer vollständigen Sicherung über Nacht sichert.

Mit SQL 2008 Management Studio müssen wir anscheinend jedes Transaktionsprotokoll einzeln auswählen. Gibt es eine Möglichkeit, es auf ein Verzeichnis zu verweisen?

Ich denke darüber nach, mehrmals am Tag eine differenzielle Sicherung durchzuführen, was einen Teil davon ausgleichen kann, aber das Durchlaufen von Dutzenden / Hunderten von Dateien nacheinander scheint ziemlich zeitaufwändig zu sein. Das Schreiben von Code für den Versuch, ein Skript zu erstellen, scheint aus unseren Kernkompetenzen viel zu weit vom Thema entfernt zu sein.

Wenn SQL Server Management Studio keinen schnelleren Weg bietet, ist möglicherweise ein Tool eines Drittanbieters verfügbar?

aSkywalker
quelle
Ja, wenn alle möglichen Mechanismen nicht funktionieren, ist es besser, Hilfe vom SQL Log Recovery Tool zu erhalten. sqlserverlogexplorer.com/restore
Jason Clark

Antworten:

10

Es gibt keine Möglichkeit, eine Reihe von Transaktionsprotokollsicherungen (oк-Ordner) anzugeben, die in SQL Server Management Studio wiederhergestellt werden sollen.

Sie finden jedoch alle Informationen zu SQL Server-Sicherungsvorgängen in der Datenbank-MSDB (Table Backupset und verwandte).

Hier ist ein Skript zum Generieren von SQL Server-Befehlen zum Wiederherstellen der Datenbank aus der Sicherung und zum Anwenden aller Transaktionsprotokollsicherungen, die von der letzten vollständigen Datenbanksicherung durchgeführt wurden. Ich denke, es sollte dir helfen.

DECLARE @databaseName sysname
DECLARE @backupStartDate datetime
DECLARE @backup_set_id_start INT
DECLARE @backup_set_id_end INT

-- set database to be used
SET @databaseName = '<your_database_name_here>' 

SELECT @backup_set_id_start = MAX(backup_set_id) 
FROM  msdb.dbo.backupset 
WHERE database_name = @databaseName AND type = 'D'

SELECT @backup_set_id_end = MIN(backup_set_id) 
FROM  msdb.dbo.backupset 
WHERE database_name = @databaseName AND type = 'D'
AND backup_set_id > @backup_set_id_start

IF @backup_set_id_end IS NULL SET @backup_set_id_end = 999999999

SELECT backup_set_id, 'RESTORE DATABASE ' + @databaseName + ' FROM DISK = ''' 
               + mf.physical_device_name + ''' WITH NORECOVERY'
FROM    msdb.dbo.backupset b,
           msdb.dbo.backupmediafamily mf
WHERE    b.media_set_id = mf.media_set_id
           AND b.database_name = @databaseName
          AND b.backup_set_id = @backup_set_id_start
UNION
SELECT backup_set_id, 'RESTORE LOG ' + @databaseName + ' FROM DISK = ''' 
               + mf.physical_device_name + ''' WITH NORECOVERY'
FROM    msdb.dbo.backupset b,
           msdb.dbo.backupmediafamily mf
WHERE    b.media_set_id = mf.media_set_id
           AND b.database_name = @databaseName
          AND b.backup_set_id >= @backup_set_id_start AND b.backup_set_id < @backup_set_id_end
          AND b.type = 'L'
UNION
SELECT 999999999 AS backup_set_id, 'RESTORE DATABASE ' + @databaseName + ' WITH RECOVERY'
ORDER BY backup_set_id
Sergey
quelle
1
Funktioniert wirklich gut, wenn Sie dieses Skript auf dem ursprünglichen Server ausführen können, aber auf einem anderen Server wiederherstellen möchten!
RealMarkusSchmidt
2
Das Skript kommt von hier mssqltips.com/sqlservertip/1243/…
Andrew Savinykh
@sergey: Sie sollten Skripte zuordnen, die Sie aus dem Web entfernen! : mssqltips.com/sqlservertip/1243/…
Mitch Wheat
4

Sie brauchen nur eine Liste von SQL-Anweisungen wie ...

RESTORE LOG AdventureWorks FROM DISK = 'C:\AdventureWorks_1.TRN' WITH NORECOVERY
GO
RESTORE LOG AdventureWorks FROM DISK = 'C:\AdventureWorks_2.TRN'
GO

So können Sie ein VB-Skript erstellen, das diese SQL einfach aus einem bestimmten Ordner für Sie generiert. Hier ist ein Beispiel: http://blogs.lessthandot.com/index.php/DataMgmt/DBAdmin/MSSQLServerAdmin/restoring-multiple-transaction-log-backu

Sobald das SQL erstellt wurde, müssen Sie nur noch überprüfen, ob es richtig aussieht, und es ausführen.

James Ryan
quelle
1

Ich wollte den SQL-basierten Ansatz der akzeptierten Antwort nicht verwenden, da ich keine erweiterten gespeicherten Prozeduren aktivieren wollte. Also habe ich ein Powershell-Skript geschrieben, um es zu tun.

Sie zeigen auf einen Ordner und es wird ein Skript generiert, das auf der letzten vollständigen Sicherung und allen nachfolgenden Transaktionsprotokollsicherungen basiert.

    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")

    $foldername = New-Object System.Windows.Forms.FolderBrowserDialog
    $foldername.rootfolder = "MyComputer"
    $foldername.ShowNewFolderButton = $false
    $foldername.SelectedPath = "E:\DatabaseBackups"

    if($foldername.ShowDialog() -eq "OK") {
        $backupPath = Get-Item($foldername.SelectedPath)    
        $databaseName = $backupPath.Name

        Write-Host($backupPath)
        Write-Host($databaseName)

        $transactionLogFiles = New-Object System.Collections.ArrayList;
        $outputFile = "Restore Database - Script.sql"
        $backupFile;


        foreach ($file in  get-childitem ($backupPath) | sort-object LastWriteTime -descending)
        {
            if ($file.Extension -eq '.trn')
            {
                [void]$transactionLogFiles.Add($file);
            }
            elseif ($file.Extension -eq '.bak')
            {
                $backupFile = $file;
                break;
            }
        }


        Set-Content $outputFile ""

        Add-Content $outputFile "USE master"
        Add-Content $outputFile "ALTER DATABASE $databaseName SET SINGLE_USER WITH ROLLBACK AFTER 5"
        Add-Content $outputFile "RESTORE DATABASE $databaseName FROM DISK = '$($backupFile.FullName)' WITH NORECOVERY";

        foreach ($file in $transactionLogFiles | sort-object LastWriteTime)
        {
            Add-Content $outputFile "RESTORE LOG $databaseName FROM DISK = '$($file.FullName)' WITH NORECOVERY";    
        }

        Add-Content $outputFile "RESTORE DATABASE $databaseName WITH RECOVERY";
        Add-Content $outputFile "ALTER DATABASE $databaseName SET MULTI_USER";
        Add-Content $outputFile "USE $databaseName" 

        Write-Host("Script generated at $outputFile");
        Write-Host "Press any key to continue ..."
        $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        Invoke-Item $outputFile

    }
Ben Curthoys
quelle
Vielen Dank! Sie haben gerade meinen Speck vor einem heißen, heißen Feuer gerettet ... msdb war beschädigt, musste das also aus dem Backup wiederherstellen und hatte keine Informationen zur Protokollkette. Ihr Skript hat mir erspart, die Transaktionsprotokoll-Wiederherstellungsskripte basierend auf dem Dateinamen von Hand erstellen zu müssen!
Agrath
Was ist, wenn Sie nur eine Datenbank und alle Transaktionsprotokolle benötigen? Was müssten Sie im Skript ändern?
user493592
Das ist es, was es tut. Eine Datenbank (die neueste) und alle Transaktionsprotokolle seitdem. Es macht keinen Sinn, Transaktionsprotokolle vor der vollständigen Sicherung zu betrachten.
Ben Curthoys