トランザクションログのバッチを1つずつではなく、どのように復元するのですか?


11

SQL Serverデータベースを使用して、トランザクションログを10分ごとにバックアップし、夜間にフルバックアップします。

SQL 2008 Management Studioを使用すると、各トランザクションログを1つずつ選択する必要があるようです。ディレクトリを指す方法はありますか?

差分バックアップを1日に数回実行することを検討していますが、これにより一部が相殺される可能性がありますが、1つずつ数十個/数百個のファイルを処理するのはかなり時間がかかるようです。スクリプトを記述しようとするコードを作成することは、コアコンピテンシーから離れすぎているようです。

SQL Server Management Studioに高速な方法がない場合、おそらくサードパーティのツールを利用できますか?


はい、可能性のあるすべてのメカニズムが機能しない場合は、SQLログ回復ツールsqlserverlogexplorer.com/restore
Jason Clark

回答:


10

SQL Server Management Studioで復元するトランザクションログのバックアップ(oкフォルダー)を指定する方法はありません。

ただし、SQL Serverバックアップ操作に関するすべての情報は、データベースMSDB(テーブルバックアップセットおよび関連)にあります。

バックアップからデータベースを復元し、最後の完全データベースバックアップから実行されたすべてのトランザクションログバックアップを適用するための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 14

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

1つのデータベースとすべてのトランザクションログが必要な場合はどうでしょうか。スクリプトで何を変更する必要がありますか?
user493592 2018年

それはそれがすることです。1つのデータベース(最新)とそれ以降のすべてのトランザクションログ。完全バックアップの前からトランザクションログを確認しても意味がありません。
ベンカーソワ2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.