Skript "Alle Datenbanken wiederherstellen"

7

Ich migriere SQL Server-DBs auf eine neue Instanz.

Mir wurde gesagt, dass es möglich ist, ein RESTORE-Skript dynamisch aus verfügbaren Sicherungen im Systemkatalog zu erstellen.

Kennt jemand ein Beispielskript, um dies zu tun?

Vielen Dank!

K09
quelle

Antworten:

11

Ich persönlich benutze sp_restorecriptgenie von Paul Brewer. Hier ist der Link zu dem SCC-Artikel, der ihn enthält. Unter 'Das Verfahren'

http://www.sqlservercentral.com/articles/Restore+database/95839/

Sobald Sie die gespeicherte Prozedur erstellt haben, führen Sie sie einfach aus, exec sp_restorescriptgenieund das Skript löscht alle Sicherungen für jede Datenbank (auch Transaktionsprotokolle) und gibt Ihnen ein Skript zum Generieren. Generiert auch die DBCC CHECKDB-Befehle, um die DBs nach dem Wiederherstellen zu überprüfen.

Ich habe dieses Skript vor ungefähr einer Stunde verwendet, damit ich eine Testwiederherstellung durchführen und meine Sicherungen überprüfen kann.

Kris Gruttemeyer
quelle
2

Unter dem folgenden Link befindet sich ein sehr gutes Skript:

So generieren Sie ein Datenbankwiederherstellungsskript in SQL Server

Basierend auf diesem Skript habe ich unten meine gespeicherte Prozedur erstellt, die sehr gut funktioniert, obwohl sie die DBCC CHECKDB nicht generiert:

Es benötigt 3 Parameter:

@Database sysname - the database name you want to generate the restore
@MovePathLog NVARCHAR(1008) - where to move the transaction log file to
@MovePathData NVARCHAR(1008) - where to move the data file(s) to

Hier ist der Code:

use master
go

IF OBJECT_ID('sp_genRestoreScripts') IS NOT NULL
   DROP PROCEDURE sp_genRestoreScripts
GO

create procedure sp_genRestoreScripts
@Database sysname,
@MovePathLog NVARCHAR(1008),
@MovePathData NVARCHAR(1008)
as begin

DECLARE @FullMediaSetID NVARCHAR(20)
DECLARE @BackupSetID NVARCHAR(20)
DECLARE @FullPath NVARCHAR(400)
DECLARE @FullPosition NVARCHAR(20)

DECLARE @LogMediaSetID NVARCHAR(20)
DECLARE @LogPath NVARCHAR(400)
DECLARE @LogPosition NVARCHAR(20)

DECLARE @DiffMediaSetID NVARCHAR(20)
DECLARE @DiffPath NVARCHAR(400)
DECLARE @DiffPosition NVARCHAR(20)

DECLARE @SQLMove NVARCHAR(MAX)
SET @SQLMove =''

IF ( @MovePathData <> '' OR @MovePathLog <> '')
BEGIN
    DECLARE @LogicalName NVARCHAR(200)
    DECLARE @FileID NVARCHAR(10)
    DECLARE @FileType NVARCHAR(10)
    DECLARE @ExtName NVARCHAR(20)

    DECLARE MoveCur CURSOR FOR 
    SELECT m.name
        ,m.file_id
        ,m.type 
    FROM sys.master_files m 
        INNER JOIN sys.databases d 
            ON m.database_id = d.database_id
    WHERE d.name = @Database

    OPEN MoveCur

    FETCH NEXT FROM MoveCur INTO @LogicalName,@FileID,@FileType

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @ExtName = CASE  
                            WHEN @FileID = 1 THEN '.mdf'
                            WHEN @FileID > 1 THEN CASE @FileType 
                                                       WHEN 0 THEN '.ndf' 
                                                       ELSE '.ldf' 
                                                  END
                       END
        SET @SQLMove = @SQLMove + CHAR(10) + '   , MOVE ' + '''' + @LogicalName + '''' 
                       + ' TO ' + '''' + 

                      CASE @FileType 
                           WHEN 0 THEN @MovePathData 
                           ELSE @MovePathLog
                      END

                       + @LogicalName + @ExtName + ''''
        FETCH NEXT FROM MoveCur INTO @LogicalName,@FileID,@FileType     
    END
    CLOSE MoveCur
    DEALLOCATE MoveCur
END


SELECT 
    @BackupSetID = backup_set_id,
    @FullMediaSetID = media_set_id, 
    @FullPosition = position
FROM msdb.dbo.backupset 
WHERE backup_set_id =
(
    SELECT MAX(backup_set_id) 
    FROM msdb.dbo.backupset 
    WHERE database_name = @Database 
        AND type='D'
    GROUP BY database_name
)

SELECT @FullPath = physical_device_name  
FROM msdb.dbo.backupmediafamily 
WHERE media_set_id = @FullMediaSetID

IF NOT EXISTS(SELECT 1 FROM msdb.dbo.backupset 
    WHERE database_name = @Database AND type IN('L','I') AND backup_set_id > @BackupSetID)
BEGIN
    PRINT REPLICATE('-',200)
    PRINT '-----------//Full backup restore only'
    PRINT REPLICATE('-',200)
    PRINT 'RESTORE DATABASE ' + @Database + CHAR(10) 
        + ' FROM DISK = ''' + @FullPath + '''' + CHAR(10) 
        + '   WITH FILE = ' + @FullPosition + ', REPLACE' + @SQLMove
END


IF EXISTS(SELECT 1 FROM msdb.dbo.backupset 
    WHERE database_name = @Database AND type='L' AND backup_set_id > @BackupSetID)
BEGIN
    PRINT REPLICATE('-',200)
    PRINT '-----------//Full backup and log backup restore '
    PRINT REPLICATE('-',200)
    PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)
        + ' FROM DISK = ''' + @FullPath + '''' + CHAR(10)
        + '   WITH FILE = ' + @FullPosition + ', NORECOVERY, REPLACE ' + @SQLMove

    DECLARE log_cursor CURSOR FOR 
    SELECT media_set_id
        ,position 
    FROM msdb.dbo.backupset 
    WHERE database_name = @Database 
        AND type='L' 
        AND backup_set_id > @BackupSetID 
    ORDER BY backup_set_id

    OPEN log_cursor

    FETCH NEXT FROM log_cursor INTO @LogMediaSetID,@LogPosition

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT @LogPath = physical_device_name  
        FROM msdb.dbo.backupmediafamily 
        WHERE media_set_id = @LogMediaSetID

        PRINT 'RESTORE Log ' + @Database + CHAR(10) 
            + ' FROM DISK = ''' + @LogPath
            + ''' WITH FILE = ' + @LogPosition + ', NORECOVERY'
        FETCH NEXT FROM log_cursor INTO @LogMediaSetID,@LogPosition
    END
    CLOSE log_cursor
    DEALLOCATE log_cursor

    PRINT 'RESTORE DATABASE ' + @Database + ' WITH RECOVERY '
END


IF EXISTS(SELECT 1 FROM msdb.dbo.backupset 
    WHERE database_name = @Database AND type='I' AND backup_set_id > @BackupSetID)
BEGIN
    PRINT REPLICATE('-',200)
    PRINT '-----------//Full backup and differential backup restore '
    PRINT REPLICATE('-',200)
    PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)  
        + ' FROM DISK = ''' + @FullPath + '''' + CHAR(10)
        + '   WITH FILE = ' + @FullPosition + ', NORECOVERY, REPLACE ' + @SQLMove

    DECLARE diff_cursor CURSOR FOR 
    SELECT media_set_id
        ,position 
    FROM msdb.dbo.backupset 
    WHERE database_name = @Database 
        AND type='I' 
        AND backup_set_id > @BackupSetID 
    ORDER BY backup_set_id

    OPEN diff_cursor

    FETCH NEXT FROM diff_cursor INTO @DiffMediaSetID,@DiffPosition

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT @DiffPath = physical_device_name  
        FROM msdb.dbo.backupmediafamily 
        WHERE media_set_id = @DiffMediaSetID

        PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)
            + ' FROM DISK = ''' + @DiffPath 
            + ''' WITH FILE = ' + @DiffPosition + ', NORECOVERY'

        FETCH NEXT FROM diff_cursor INTO @DiffMediaSetID,@DiffPosition
    END
    CLOSE diff_cursor
    DEALLOCATE diff_cursor

    PRINT 'RESTORE DATABASE ' + @Database + ' WITH RECOVERY '
END
end 
GO

So führen Sie die Prozedur für eine einzelne Datenbank aus:

use master
go
exec sp_genRestoreScripts
        @Database ='CAAltosextracts',
        @MovePathLog ='F:\logs\',
        @MovePathData ='e:\DATA\'

und für mehrere Datenbanken verwende ich die gespeicherte Prozedur sp_foreachdb

     declare @db_list NVARCHAR(MAX)


     SELECT @db_list  = STUFF((
                                SELECT ', ' + name FROM sys.databases
                                WHERE name NOT IN ('DBA','TABLEBACKUPS','MASTER','MSDB','MODEL','TEMPDB')
                                FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '')

     --exec sp_foreachdb @database_list = @db_list
              --       ,@command='use ?; print db_name() + char(13)'   

     exec sp_foreachdb @database_list = @db_list
                     ,@command='
                                 exec sp_genRestoreScripts
                                        @Database =[?],
                                        @MovePathLog =''F:\logs\'',
                                        @MovePathData =''E:\DATA\'' 
                               ' 
Marcello Miorelli
quelle
Es wird der folgende Fehler ausgegeben: Ich verwende Ihr Multi-Datenbank-Skript. Nachricht 103, Ebene 15, Status 4, Zeile 3 Die Kennung, die mit '[ABC], @MovePathLog =' F: \ Programme \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER beginnt \ MSSQ 'ist zu lang. Maximale Länge ist 128.
Feivel
@Database sysnamedas sind 128 Zeichen. Möchten Sie Datenbanknamen größer als 128? Nein danke.
Marcello Miorelli
0

Ich migriere SQL Server-DBs auf eine neue Instanz.

Sie können dbatools - Copy-DbaDatabase verwenden , um eine Sicherung / Wiederherstellung von einer Quelle zu mehreren Zielen durchzuführen .

Für die Wiederherstellung von dbatools können Sie mit Restore-DbaDatabase nur auf einen Sicherungsspeicherort verweisen oder Ihrem msdb-Sicherungsverlauf vertrauen, um Befehle zu erstellen, und Sie können auch eine Wiederherstellung zu einem bestimmten Zeitpunkt durchführen. Es ermittelt automatisch Full-, Diff- und Tlogs.

Sie können Ihre Wiederherstellungsskripte sogar mit Export-DbaScript in eine Datei generieren .

Hinweis: Ich habe sowohl dbatools als auch sp_restoreGene verwendet - beide sind wirklich gut. Der Pluspunkt von dbatools ist, dass Sie andere Cmdlets für Ihre gesamte Serververwaltung verwenden können.

Kin Shah
quelle