Làm cách nào để khôi phục một loạt nhật ký giao dịch thay vì từng cái một


11

Tôi có một cơ sở dữ liệu SQL Server sao lưu nhật ký giao dịch cứ sau 10 phút, với một bản sao lưu đầy đủ qua đêm.

Sử dụng SQL 2008 Management studio, chúng tôi dường như phải chọn từng nhật ký giao dịch. Có cách nào để trỏ nó vào một thư mục?

Tôi đang xem xét việc chạy một bản sao lưu vi sai nhiều lần trong ngày, điều này có thể bù đắp một phần trong số này, nhưng việc thực hiện từng cái một qua hàng chục / hàng trăm tệp dường như khá tốn thời gian. Viết mã để cố gắng viết kịch bản có vẻ quá lạc đề so với năng lực cốt lõi của chúng tôi.

Nếu SQL Server Management Studio không có cách nhanh hơn, có lẽ có một công cụ bên thứ ba có sẵn?


có, nếu tất cả các cơ chế có thể không hoạt động thì tốt hơn là nhờ trợ giúp từ Công cụ khôi phục nhật ký SQL sqlserverlogexplorer.com/restore
Jason Clark

Câu trả lời:


10

Không có cách nào để chỉ định một loạt các bản sao lưu nhật ký giao dịch (thư mục oк) để khôi phục trong phòng thu SQL Server Management.

Nhưng bạn có thể tìm thấy tất cả thông tin về các hoạt động sao lưu của SQL Server trong cơ sở dữ liệu MSDB (sao lưu bảng và có liên quan).

Đây là kịch bản để tạo các lệnh SQL Server để khôi phục cơ sở dữ liệu từ bản sao lưu và áp dụng tất cả các bản sao lưu nhật ký giao dịch được thực hiện từ bản sao lưu cơ sở dữ liệu đầy đủ cuối cùng. Tôi nghĩ nó sẽ giúp bạn.

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
Hoạt động thực sự tuyệt vời nếu bạn có thể chạy tập lệnh này trên máy chủ gốc nhưng muốn khôi phục trên máy chủ khác!
realMarkusSchmidt

2
Kịch bản xuất phát từ đây mssqltips.com/sqlservertip/1243/ Kẻ
Andrew Savinykh

@sergey: bạn nên ghi các tập lệnh mà bạn nâng lên từ web! : mssqltips.com/sqlservertip/1243/ Ấn
Mitch Wheat

4

bạn chỉ cần một danh sách các câu lệnh sql như ...

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

Vì vậy, bạn có thể tạo một tập lệnh VB dễ dàng tạo SQL này cho bạn từ một thư mục nhất định. Dưới đây là một ví dụ http://bloss.lessthandot.com/index.php/DataMgmt/DBAdmin/MSQueryServerAdmin/restoring-multipl-transaction-log-backu

Một khi nó đã tạo SQL, bạn chỉ cần kiểm tra xem nó có đúng không và chạy nó.



1

Tôi không muốn sử dụng cách tiếp cận dựa trên SQL của câu trả lời được chấp nhận, vì tôi không muốn kích hoạt các thủ tục lưu trữ mở rộng. Vì vậy, tôi đã viết một kịch bản powershell để làm điều đó.

Bạn trỏ nó vào một thư mục và nó tạo ra một kịch bản dựa trên bản sao lưu đầy đủ gần đây nhất và tất cả các bản sao lưu nhật ký giao dịch tiếp theo.

    [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

    }

Cảm ơn bạn! Bạn vừa lưu thịt xông khói của tôi khỏi lửa nóng ... msdb đã bị hỏng nên phải khôi phục lại từ bản sao lưu và không có thông tin chuỗi nhật ký. Tập lệnh của bạn đã cứu tôi khỏi phải xây dựng tập lệnh khôi phục nhật ký giao dịch bằng tay dựa trên tên tệp!
agrath

Điều gì nếu bạn chỉ muốn một cơ sở dữ liệu và tất cả các nhật ký giao dịch? Bạn cần gì để thay đổi trong kịch bản?
dùng493592

Đó là những gì nó làm. Một cơ sở dữ liệu (gần đây nhất) và tất cả các nhật ký giao dịch kể từ đó. Không có điểm nào nhìn vào nhật ký giao dịch từ trước khi sao lưu toàn bộ.
Ben Curthoys
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.