하나씩 트랜잭션 로그를 일괄 적으로 복원하는 방법


12

밤새 전체 백업으로 10 분마다 트랜잭션 로그를 백업하는 SQL Server 데이터베이스가 있습니다.

SQL 2008 Management Studio를 사용하면 각 트랜잭션 로그를 하나씩 선택해야합니다. 디렉토리를 가리킬 방법이 있습니까?

하루에 여러 번 차등 백업을 실행하는 것을 고려하고 있는데,이 중 일부는 상쇄 될 수 있지만 수십 / 수백 개의 파일을 하나씩 실행하는 데 시간이 많이 걸리는 것 같습니다. 스크립트 작성을위한 코드 작성은 핵심 역량과는 거리가 멀다.

SQL Server Management Studio가 더 빠른 방법이 없다면 타사 도구가 있습니까?


예, 가능한 모든 메커니즘이 작동하지 않으면 SQL 로그 복구 도구 ( sqlserverlogexplorer.com/restore)의
— Jason Clark

답변:


11

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

2
이 스크립트는 여기에서 온다 mssqltips.com/sqlservertip/1243/...
— 앤드류 Savinykh에게

@ sergey : 당신이 웹에서 들어 올리는 스크립트의 속성을 지정해야합니다! : mssqltips.com/sqlservertip/1243/…
— Mitch Wheat


4

다음과 같은 SQL 문 목록이 필요합니다 ...

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

따라서 주어진 폴더에서이 SQL을 쉽게 생성하는 VB 스크립트를 만들 수 있습니다. 다음은 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

그것이하는 일입니다. 그 이후로 하나의 데이터베이스 (가장 최근)와 모든 트랜잭션 로그. 전체 백업 이전의 트랜잭션 로그를 볼 필요는 없습니다.
— Ben Curthoys
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.