¿Cómo restauro un lote de registros de transacciones en lugar de uno por uno?


11

Tengo una base de datos de SQL Server que realiza una copia de seguridad de los registros de transacciones cada 10 minutos, con una copia de seguridad completa durante la noche.

Al usar el estudio de administración SQL 2008, parece que tenemos que seleccionar cada registro de transacciones uno por uno. ¿Hay alguna manera de apuntarlo a un directorio?

Estoy considerando ejecutar una copia de seguridad diferencial varias veces al día, lo que puede compensar algo de esto, pero pasar uno por uno a través de docenas / cientos de archivos parece consumir bastante tiempo. Escribir código para intentar escribir un script parece estar demasiado alejado del tema de nuestras competencias centrales.

Si SQL Server Management Studio no tiene una forma más rápida, ¿tal vez hay una herramienta de terceros disponible?


sí, si todo el mecanismo posible no funciona, entonces es mejor obtener ayuda de SQL Log Recovery Tool sqlserverlogexplorer.com/restore
Jason Clark

Respuestas:


10

No hay formas de especificar un montón de copias de seguridad del registro de transacciones (carpeta oк) para restaurar en el estudio de administración de SQL Server.

Pero puede encontrar toda la información sobre las operaciones de copia de seguridad de SQL Server en la base de datos MSDB (conjunto de copia de seguridad de tabla y relacionado).

Aquí hay un script para generar comandos de SQL Server para restaurar la base de datos desde la copia de seguridad y aplicar todas las copias de seguridad de los registros de transacciones realizadas desde la última copia de seguridad completa de la base de datos. Creo que debería ayudarte.

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

1
¡Funciona realmente bien si puede ejecutar este script en el servidor original pero desea restaurar en otro servidor!
realMarkusSchmidt


@sergey: ¡debes atribuir los scripts que levantas de la web! : mssqltips.com/sqlservertip/1243/…
Mitch Wheat

4

solo necesita una lista de sentencias sql como ...

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

Por lo tanto, puede crear un script VB que genere fácilmente este SQL para usted desde una carpeta determinada. Aquí hay un ejemplo http://blogs.lessthandot.com/index.php/DataMgmt/DBAdmin/MSSQLServerAdmin/restoring-multiple-transaction-log-backu

Una vez que ha creado el SQL, solo necesita verificar que se vea bien y ejecutarlo.



1

No quería usar el enfoque basado en SQL de la respuesta aceptada, porque no quería habilitar procedimientos almacenados extendidos. Entonces escribí un script de PowerShell para hacerlo.

Lo apuntas a una carpeta y genera una secuencia de comandos basada en la copia de seguridad completa más reciente y todas las copias de seguridad del registro de transacciones posteriores.

    [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

    }

¡Gracias! Acabas de salvar mi tocino de un fuego ardiente ... msdb estaba dañado, así que tuve que restaurarlo desde la copia de seguridad y no tenía la información de la cadena de registro. ¡Su secuencia de comandos me salvó de tener que construir las secuencias de comandos de restauración del registro de transacciones a mano según el nombre del archivo!
agrath

¿Qué sucede si solo desea una base de datos y todos los registros de transacciones? ¿Qué necesitarías cambiar en el guión?
user493592

Eso es lo que hace. Una base de datos (la más reciente) y todos los registros de transacciones desde entonces. No tiene sentido mirar los registros de transacciones antes de la copia de seguridad completa.
Ben Curthoys
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.