Як відновити партію журналів транзакцій, а не по черзі


11

У мене є база даних SQL Server, яка створює резервні копії журналів транзакцій кожні 10 хвилин з повним резервним копією протягом ночі.

Використовуючи студію управління SQL 2008, нам здається, що потрібно вибирати кожен журнал транзакцій по одному. Чи є спосіб вказати його на каталог?

Я розглядаю запуск диференціального резервного копіювання кілька разів на день, що може компенсувати деяку частину цього, але проходження по одному через десятки / сотні файлів, здається, займає досить багато часу. Написання коду, щоб спробувати скрипт, здається, це занадто поза темою від наших основних компетенцій.

Якщо SQL Server Management Studio не має більш швидкого шляху, можливо, є інший інструмент?


так, якщо весь можливий механізм не працює, тоді краще скористатися допомогою інструмента відновлення журналу SQL sqlserverlogexplorer.com/restore
Джейсон Кларк

Відповіді:


10

Немає способів вказати купу резервних копій журналу транзакцій (папка ok) для відновлення в студії управління SQL Server.

Але ви можете знайти всю інформацію про операції з резервного копіювання 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

2
Сценарій походить звідси mssqltips.com/sqlservertip/1243/…
Андрій Савіних

@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

Таким чином, ви можете створити сценарій VB, який легко генерує цей SQL для вас із заданої папки. Ось приклад http://blogs.lessthandot.com/index.php/DataMgmt/DBAdmin/MSSQLServerAdmin/restoring-multiple-transaction-log-backu

Після того, як він створив SQL, вам просто потрібно перевірити, чи він виглядає правильно, і запустити його.


4

Ось приклад того, як можна автоматично генерувати сценарій відновлення SQL Server із резервних файлів у каталозі за допомогою TSQL:

Автоматичне створення сценарію відновлення SQL Server із резервних файлів у каталозі

Автоматичне створення сценаріїв відновлення бази даних SQL Server


1

Я не хотів використовувати підхід, заснований на SQL, прийнятої відповіді, тому що не хотів включати розширені збережені процедури. Тому я написав скрипт з силою для цього.

Ви вказуєте його на папку, і вона генерує сценарій на основі останньої повної резервної копії та всіх наступних резервних копій журналу транзакцій.

    [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 був пошкоджений, тому довелося відновити його з резервного копіювання та не мав інформації про ланцюжок журналу. Ваш сценарій врятував мене від необхідності створювати сценарії відновлення журналу транзакцій вручну на основі імені файлу!
агра

Що робити, якщо ви хочете лише одну базу даних та всі журнали транзакцій? Що вам потрібно змінити в сценарії?
користувач493592

Ось що це робить. Одна база даних (найновіша) та всі журнали транзакцій з тих пір. Немає сенсу дивитись на журнали транзакцій з моменту попередньої резервної копії.
Бен Кертойс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.