Bagaimana cara mengembalikan kumpulan log transaksi daripada satu per satu


11

Saya memiliki database SQL Server yang mencadangkan log transaksi setiap 10 menit, dengan cadangan penuh semalam.

Menggunakan SQL 2008 Management studio kami sepertinya harus memilih setiap transaksi log satu per satu. Apakah ada cara untuk mengarahkannya ke direktori?

Saya sedang mempertimbangkan untuk menjalankan cadangan diferensial beberapa kali sehari, yang dapat mengimbangi beberapa dari ini, tetapi pergi satu per satu hingga puluhan / ratusan file tampaknya cukup memakan waktu. Menulis kode untuk mencoba skrip tampaknya terlalu jauh dari kompetensi inti kami.

Jika SQL Server Management Studio tidak memiliki cara yang lebih cepat, mungkin ada alat pihak ketiga yang tersedia?


ya, jika semua mekanisme yang mungkin tidak berhasil maka lebih baik untuk mengambil bantuan dari SQL Log Recovery Tool sqlserverlogexplorer.com/restore
Jason Clark

Jawaban:


10

Tidak ada cara untuk menentukan sekelompok cadangan log transaksi (folder Oк) untuk memulihkan di SQL Server Management studio.

Tetapi Anda dapat menemukan semua informasi tentang operasi cadangan SQL Server di database MSDB (tabel backupset dan terkait).

Berikut ini skrip untuk membuat perintah SQL Server untuk memulihkan database dari cadangan dan menerapkan semua transaksi log cadangan yang dilakukan dari cadangan database lengkap terakhir. Saya pikir itu akan membantu Anda.

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
Bekerja sangat bagus jika Anda dapat menjalankan skrip ini di server asli tetapi ingin mengembalikan pada server lain!
realMarkusSchmidt


@sergey: Anda harus atribut skrip yang Anda angkat dari web! : mssqltips.com/sqlservertip/1243/…
Mitch Wheat

4

Anda hanya perlu daftar pernyataan sql seperti ...

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

Jadi Anda bisa membuat skrip VB yang dengan mudah menghasilkan SQL ini untuk Anda dari folder yang diberikan. Berikut ini contohnya http://blogs.lessthandot.com/index.php/DataMgmt/DBAdmin/MSSQLServerAdmin/restoring-multiple-transaction-log-backu

Setelah SQL dibuat, Anda hanya perlu memeriksa apakah itu terlihat benar dan menjalankannya.



1

Saya tidak ingin menggunakan pendekatan berbasis SQL dari jawaban yang diterima, karena saya tidak ingin mengaktifkan prosedur tersimpan yang panjang. Jadi saya menulis skrip PowerShell untuk melakukannya.

Anda mengarahkannya ke folder, dan menghasilkan skrip berdasarkan cadangan lengkap terbaru, dan semua cadangan log transaksi selanjutnya.

    [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

    }

Terima kasih! Anda baru saja menyelamatkan daging saya dari api panas ... msdb rusak sehingga harus memulihkannya dari cadangan dan tidak memiliki info rantai log. Skrip Anda menyelamatkan saya dari keharusan membuat skrip pemulihan log transaksi dengan tangan berdasarkan nama file!
marah

Bagaimana jika Anda hanya ingin satu database dan semua log transaksi? Apa yang perlu Anda ubah dalam naskah?
user493592

Itu yang dilakukannya. Satu basis data (terbaru) dan semua log transaksi sejak saat itu. Tidak ada gunanya melihat log transaksi sebelum cadangan lengkap.
Ben Curthoys
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.