[SQL] Automatisation d'un restore de base de données

Voici une méthode qui permet d'effectuer un restore de base de données via un fichier .bak et depuis SQL Serveur (ou SSIS dans une tâche de script SQL).

Le petit plus de ce script consiste à placer les fichiers Data (mdf) et Log (ldf) à un endroit paramétrable (le script final est disponible à la fin de l'article).

La commande de base est:

RESTORE DATABASE MaBase
FROM DISK = 'D:\MSSQLSERVER\MSSQL\BACKUPS\mon_bak.bak'    


Cependant cette commande copiera les fichiers mdf et ldf contenus dans le .bak à l'endroit par défaut et ne permet donc pas de spécifier l'endroit où l'on souhaite placer ces fichiers.

Pour cela il faut utiliser la commande suivante:


RESTORE DATABASE MaBase
FROM DISK = 'D:\MSSQLSERVER\MSSQL\BACKUPS\mon_bak.bak'    
WITH
MOVE 'MaBaseOld' TO 'D:\MSSQLSERVER\MSSQL\DATA\' ,
MOVE 'MaBaseOld_log' TO 'D:\MSSQLSERVER\MSSQL\LOGS\',
REPLACE


Maintenant intéressons nous aux fichiers "MaBaseOLD" et "MaBaseOld_log" qui sont contenus dans le fichier mon_bak.bak.

Ces fichiers correspondent aux noms des mdf et ldf de la base à partir de laquelle le .bak a été généré.

Afin de ne pas être dépendant du nom de la base source et de ses fichiers mdf et ldf, il semble intéressant de récupérer ces informations de manière dynamique.

La commande suivante permet de récupérer ces informations en éxécutant une requête FILELISTONLY sur le fichier bak.


Exec ('RESTORE FILELISTONLY FROM DISK = ''D:\MSSQLSERVER\MSSQL\BACKUPS\mon_bak.bak''')


Cette requête renvoie les informations suivantes:


La colonne qui nous intéresse est "LogicalName" car c'est elle qui sera utilisée dans notre commande Restore.
Remarque: Sous SQL Serveur 2005 cette requête ne RETOURNE PAS de colonne "TDEThumbprint" alors que sous SQL Serveur 2008 cette colonne est retournée (penser à adapter le script final pour la table temporaire).

Le script suivant nous permet donc de conclure cet article en récupérant dynamiquement le nom des fichiers logiques et en restaurant la base de données:



/*
@DestDBName: Le nom de la base une fois restaurée
@BackUpPath: Le chemin vers la backup (NON UNC ou bien de type '\\srv-monserveur\Un_dossier_partagé\Backups\mon_bak.bak'
@DST_MDF_PATH: Le chemin où stocker le fihier mdf (NON UNC!!)
@DST_LDF_PATH: Le chemin où stocker le fihier ldf (NON UNC!!)
@TMP: La table temporaire nous permettant de récupérer les noms des fichiers logiques
*/

DECLARE @DestDBName AS VARCHAR(50)
  ,@BackUpPath AS VARCHAR(255)
  ,@DST_MDF_PATH AS VARCHAR(1000)
  ,@DST_LDF_PATH AS VARCHAR(1000)
  ,@SQL AS VARCHAR(1000)
 
 SET @DestDBName = 'MyNew_DataBase'
 SET @BackUpPath = 'D:\MSSQLSERVER\MSSQL\BACKUPS\mon_bak.bak'
 SET @DST_MDF_PATH = 'D:\MSSQLSERVER\MSSQL\DATA\'
 SET @DST_LDF_PATH = 'D:\MSSQLSERVER\MSSQL\LOGS\'

DECLARE @TMP AS TABLE (
       LogicalName  nvarchar(128)
       ,PhysicalName nvarchar(260)
       ,Type  char(1)
       ,FileGroupName  nvarchar(128)
       ,Size  numeric(20,0)
       ,MaxSize  numeric(20,0)
       ,FileID  bigint
       ,CreateLSN  numeric(25,0)
       ,DropLSN  numeric(25,0) NULL
       ,UniqueID  uniqueidentifier
       ,ReadOnlyLSN  numeric(25,0) NULL
       ,ReadWriteLSN numeric(25,0) NULL
       ,BackupSizeInBytes  bigint
       ,SourceBlockSize  int
       ,FileGroupID  int
       ,LogGroupGUID  uniqueidentifier
       ,DifferentialBaseLSN  numeric(25,0)
       ,DifferentialBaseGUID uniqueidentifier
       ,IsReadOnly  bit
       ,IsPresent  bit
       ,TDEThumbprint  varbinary(32) /*SQL 2008*/
)

INSERT INTO @TMP (LogicalName,PhysicalName,[Type],FileGroupName,Size,MaxSize,FileID,CreateLSN,DropLSN,UniqueID,ReadOnlyLSN,ReadWriteLSN,BackupSizeInBytes,SourceBlockSize
                           ,FileGroupID,LogGroupGUID,DifferentialBaseLSN,DifferentialBaseGUID,IsReadOnly,IsPresent,TDEThumbprint/*SQL 2008*/
)
 Exec ('RESTORE FILELISTONLY FROM DISK = '''+ @BackUpPath +'''')

SET @SQL =
  'RESTORE DATABASE ' + @DestDBName + ' FROM DISK = '''+ @BackUpPath +'''
   WITH
     MOVE '''+ (SELECT logicalname from @TMP WHERE Type = 'D') +''' TO '''+ @DST_MDF_PATH  + ''' ,
     MOVE '''+ (SELECT logicalname from @TMP WHERE Type = 'L') +''' TO '''+ @DST_LDF_PATH +''',
     REPLACE'
Exec (@SQL)

Aucun commentaire:

Enregistrer un commentaire