Como restaurar um lote de logs de transações em vez de um por um

11

Eu tenho um banco de dados do SQL Server que faz backup dos logs de transações a cada 10 minutos, com um backup completo durante a noite.

Usando o SQL 2008 Management studio, parece que precisamos selecionar cada log de transações, um por um. Existe alguma maneira de apontar para um diretório?

Estou pensando em executar um backup diferencial várias vezes ao dia, o que pode compensar parte disso, mas analisar um por um através de dezenas / centenas de arquivos parece consumir bastante tempo. Escrever um código para tentar criar um script parece muito fora do tópico das nossas principais competências.

Se o SQL Server Management Studio não tiver uma maneira mais rápida, talvez haja uma ferramenta de terceiros disponível?

aSkywalker
fonte
sim, se todo o possível mecanismo não funciona, então o seu melhor para ter a ajuda de SQL Log Recovery Tool sqlserverlogexplorer.com/restore
Jason Clark

Respostas:

10

Não há maneiras de especificar vários backups de log de transações (pasta ok) para restaurar no SQL Server Management studio.

Mas você pode encontrar todas as informações sobre as operações de backup do SQL Server no banco de dados MSDB (tabela backupsetset e afins).

Aqui está o script para gerar comandos do SQL Server para restaurar o banco de dados a partir do backup e aplicar todos os backups dos logs de transações executados no último backup completo do banco de dados. Eu acho que deveria ajudá-lo.

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
fonte
1
Funciona muito bem se você pode executar esse script no servidor original, mas deseja restaurar em outro servidor!
realMarkusSchmidt 21/02
2
O script vem daqui mssqltips.com/sqlservertip/1243/…
Andrew Savinykh
@sergey: você deve atribuir scripts que retira da web! : mssqltips.com/sqlservertip/1243/…
Mitch Wheat
4

você só precisa de uma lista de instruções sql como ...

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

Assim, você pode criar um script VB que facilmente gera esse SQL para você a partir de uma determinada pasta. Aqui está um exemplo http://blogs.lessthandot.com/index.php/DataMgmt/DBAdmin/MSSQLServerAdmin/restoring-multiple-transaction-log-backu

Depois de criar o SQL, basta verificar se ele está correto e executá-lo.

JamesRyan
fonte
1

Eu não queria usar a abordagem baseada em SQL da resposta aceita, porque não queria habilitar procedimentos armazenados estendidos. Então, eu escrevi um script do PowerShell para fazer isso.

Você o aponta para uma pasta e gera um script com base no backup completo mais recente e em todos os backups subsequentes do log de transações.

    [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
fonte
Obrigado! Você acabou de salvar meu bacon de um incêndio quente e quente ... O msdb estava corrompido, portanto, foi necessário restaurá-lo do backup e não tinha as informações da cadeia de logs. Seu script me salvou de ter que criar manualmente os scripts de restauração do log de transações com base no nome do arquivo!
precisa saber é
E se você quiser apenas um banco de dados e todos os logs de transações? O que você precisaria mudar no script?
user493592
É o que faz. Um banco de dados (o mais recente) e todos os logs de transações desde então. Não faz sentido olhar para os logs de transações anteriores ao backup completo.
Ben Curthoys