如何还原一批事务日志,而不是一个接一个地还原


11

我有一个SQL Server数据库,该数据库每10分钟备份一次事务日志,并进行一整夜的完整备份。

使用SQL 2008 Management Studio,我们似乎必须一个一个地选择每个事务日志。有什么办法可以将其指向目录吗?

我正在考虑一天执行几次差异备份,这可能会抵消其中的一部分,但是要逐个处理数十个/百个文件似乎很耗时。编写代码以尝试编写脚本似乎与我们的核心能力相差太远。

如果SQL Server Management Studio没有更快的方法,那么也许有第三方工具可用?


是的,如果所有可能的机制不工作那么它最好采取从SQL日志恢复工具帮助sqlserverlogexplorer.com/restore
杰森·克拉克

Answers:


10

无法在SQL Server Management Studio中指定要还原的一堆事务日志备份(oк文件夹)。

但是您可以在数据库MSDB中找到有关SQL Server备份操作的所有信息(表备份集和相关表)。

这是用于生成SQL Server命令以从备份还原数据库并应用从上次完整数据库备份执行的所有事务日志备份的脚本。我认为它应该对您有帮助。

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
如果您可以在原始服务器上运行此脚本,但又想在另一台服务器上还原该脚本,则效果非常好!
realMarkusSchmidt 2014年


@sergey:您应该将您从网络上提取的脚本归因!:mssqltips.com/sqlservertip/1243/...
米奇小麦

4

您只需要像这样的sql语句列表...

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

因此,您可以制作一个VB脚本,该脚本可以轻松地从给定文件夹为您生成此SQL。这是一个示例http://blogs.lessthandot.com/index.php/DataMgmt/DBAdmin/MSSQLServerAdmin/restoring-multiple-transaction-log-backu

一旦创建了SQL,您只需要检查它看起来是否正确并运行它即可。



1

我不想使用接受答案的基于SQL的方法,因为我不想启用扩展存储过程。因此,我编写了一个powershell脚本来执行此操作。

您将其指向一个文件夹,它会根据最新的完整备份以及所有后续的事务日志备份生成脚本。

    [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

    }

谢谢!您刚刚从热火中保存了我的培根... msdb损坏,因此必须从备份中恢复它,并且没有日志链信息。您的脚本使我免于必须手动基于文件名构建事务日志恢复脚本的麻烦!
agrath

如果您只想要一个数据库和所有事务日志该怎么办?您需要在脚本中进行哪些更改?
user493592

那就是它的作用。此后是一个数据库(最新的)和所有事务日志。完全备份之前没有必要查看事务日志。
本·柯索斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.