IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Administration SQL Server Discussion :

Restauration sur un serveur de préprod


Sujet :

Administration SQL Server

  1. #1
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut Restauration sur un serveur de préprod
    Bonjour,
    Une fois n'est pas coutume, je ne viens pas poster un problème mais plutôt une solution

    Ci après le code la procédure pour laquelle il me serait agréable d'avoir vos commentaires/corrections.


    Problématique : rafraichir le serveur de préprod avec les données de la prod.
    Facile, me direz vous, il suffit de restaurer le dernier backup.
    Mais, si on est exigeant, on voudrait bien par la même occasion tester la restauration "grandeur réelle" c'est à dire :
    -1 sur un autre serveur (le serveur de préprod c'st parfait )
    -2 en restaurant "au mieux" c'est à dire la dernière complète + la dernière différentielle si elle existe et la suite de journaux disponibles
    -3 en imaginant ne plus avoir accès à l'historique des backup de msdb du serveur source
    -4 en restaurant pas forcément sur les mêmes disques (chemins)

    Je vous propose donc de tester/commenter/partager cette procédure qu'on peut créer dans une base "boite_a_outils" (ou dans master...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
     
    drop procedure if exists Restore_from_folder
    go
    Create procedure Restore_from_folder
    /*  This procedure is intend to deal with backup folder made by maintenance plan without using backup history.
        The common way to use it is to have a freshest copy of a production DB to preprod server.
        
        Nb: There is only one destination datafile folder because 
            -I don't want deal with table parameter
            -It's usual for a preprod server
            -If you set null, no path change
        
        Provided by Michel Priori (Fr)
        Script version : 20181020
        @@version >=  SQL Server 2014 Service Pack 1 
    */
         @Backup_Path_Folder          nvarchar(255) 
        ,@databasename                nvarchar(255) 
        ,@Restore_Datafile_Folder     nvarchar(255) = null
        ,@Restore_Logfile_Folder      nvarchar(255) = null
        ,@Execution_Mode              int = 1 /*  1:Default. List All finded backupset
                                                  2:Script   Verifyonly most recent backup sequence
                                                  3:Script   Restore most recent backup sequence
                                                  4:Execute  Verifyonly most recent backup sequence
                                                  5:Execute  Restore most recent backup sequence
                                              */
    As
    begin
        set nocount on
        select @Backup_Path_Folder = case when right(@Backup_Path_Folder,1)=char(92) 
                                           then left(@Backup_Path_Folder, len(@Backup_Path_Folder)-1)
                                           else @Backup_Path_Folder
                                     end
        select @Restore_Datafile_Folder = case when right(@Restore_Datafile_Folder,1)=char(92) 
                                           then left(@Restore_Datafile_Folder, len(@Restore_Datafile_Folder)-1)
                                           else @Restore_Datafile_Folder
                                     end
        select @Restore_Logfile_Folder = case when right(@Restore_Logfile_Folder,1)=char(92) 
                                           then left(@Restore_Logfile_Folder, len(@Restore_Logfile_Folder)-1)
                                           else @Restore_Logfile_Folder
                                     end                                 
        /*
        ** Catch list of existing backupfiles 
        **
        */
        DECLARE @DirectoryTree TABLE  (
             id int IDENTITY(1,1)
            ,subdirectory nvarchar(512)
            ,depth int
            ,isfile bit);
        DECLARE 
           @RESTORE_headeronly as TABLE
           (Backup_entry           int IDENTITY(1,1)
           ,backupFilename         nvarchar(512)
           ,BackupName             nvarchar(128)
           ,BackupDescription      nvarchar(255)
           ,BackupType             smallint
           ,ExpirationDate         datetime
           ,Compressed             bit
           ,Position               smallint
           ,DeviceType             tinyint
           ,UserName               nvarchar(128)
           ,ServerName             nvarchar(128)
           ,DatabaseName           nvarchar(128)
           ,DatabaseVersion        int
           ,DatabaseCreationDate   datetime
           ,BackupSize             numeric(20, 0)
           ,FirstLSN               numeric(25, 0)
           ,LastLSN                numeric(25, 0)
           ,CheckpointLSN          numeric(25, 0)
           ,DatabaseBackupLSN      numeric(25, 0)
           ,BackupStartDate        datetime
           ,BackupFinishDate       datetime
           ,SortOrder              smallint
           ,[CodePage]             smallint
           ,UnicodeLocaleId        int
           ,UnicodeComparisonStyle int
           ,CompatibilityLevel     tinyint
           ,SoftwareVendorId       int
           ,SoftwareVersionMajor   int
           ,SoftwareVersionMinor   int
           ,SoftwareVersionBuild   int
           ,MachineName            nvarchar(128)
           ,Flags                  int
           ,BindingId              uniqueidentifier
           ,RecoveryForkId         uniqueidentifier
           ,Collation              nvarchar(128)
           ,FamilyGUID             uniqueidentifier
           ,HasBulkLoggedData      bit
           ,IsSnapshot             bit
           ,IsReadOnly             bit
           ,IsSingleUser           bit
           ,HasBackupChecksums     bit
           ,IsDamaged              bit
           ,BeginsLogChain         bit
           ,HasIncompleteMetaData  bit
           ,IsForceOffline         bit
           ,IsCopyOnly             bit
           ,FirstRecoveryForkID    uniqueidentifier
           ,ForkPointLSN           numeric(25, 0)
           ,RecoveryModel          nvarchar(60)
           ,DifferentialBaseLSN    numeric(25, 0)
           ,DifferentialBaseGUID   uniqueidentifier
           ,BackupTypeDescription  nvarchar(60)
           ,BackupSetGUID          uniqueidentifier
           ,CompressedBackupSize   bigint
           ,Containment            tinyint
           ,KeyAlgorithm           nvarchar(32)    
           ,EncryptorThumbprint    varbinary(20)   
           ,EncryptorType          nvarchar(32)    
           );
        Declare  
            @C1_subdirectory       nvarchar(512)
           ,@File_to_Restore       nvarchar(512)
           ,@STR_SQL               nvarchar(max)
        INSERT INTO @DirectoryTree (subdirectory,depth,isfile)
           EXEC master.sys.xp_dirtree @Backup_Path_Folder,1,1;
        /*
        ** Catch list of backusets of claim database in backupfiles
        **
        */
        Declare C1 cursor for
           SELECT subdirectory 
           FROM @DirectoryTree 
           WHERE isfile = 1 
              and right(subdirectory,3) in ('bak','trn')
           ORDER BY id;
        Open C1;
        Fetch C1 into @C1_subdirectory;
        WHILE @@fetch_Status = 0
        BEGIN
           set @File_to_Restore = @Backup_Path_Folder+char(92)+@C1_subdirectory
           set @STR_SQL = 'RESTORE headeronly from disk = ''' + @File_to_Restore+'''';
           insert into @RESTORE_headeronly 
              (BackupName           ,BackupDescription    ,BackupType            ,ExpirationDate          
               ,Compressed          ,Position             ,DeviceType            ,UserName              
               ,ServerName          ,DatabaseName         ,DatabaseVersion       ,DatabaseCreationDate  
               ,BackupSize          ,FirstLSN             ,LastLSN               ,CheckpointLSN          
               ,DatabaseBackupLSN   ,BackupStartDate      ,BackupFinishDate      ,SortOrder              
               ,[CodePage]          ,UnicodeLocaleId      ,UnicodeComparisonStyle,CompatibilityLevel      
               ,SoftwareVendorId    ,SoftwareVersionMajor ,SoftwareVersionMinor  ,SoftwareVersionBuild  
               ,MachineName         ,Flags                ,BindingId             ,RecoveryForkId          
               ,Collation           ,FamilyGUID           ,HasBulkLoggedData     ,IsSnapshot          
               ,IsReadOnly          ,IsSingleUser         ,HasBackupChecksums    ,IsDamaged              
               ,BeginsLogChain      ,HasIncompleteMetaData,IsForceOffline        ,IsCopyOnly          
               ,FirstRecoveryForkID ,ForkPointLSN         ,RecoveryModel         ,DifferentialBaseLSN      
               ,DifferentialBaseGUID,BackupTypeDescription,BackupSetGUID         ,CompressedBackupSize  
               ,Containment         ,KeyAlgorithm         ,EncryptorThumbprint   ,EncryptorType
               )
              exec (@str_sql);
            update @RESTORE_headeronly
                 set backupFilename = @C1_subdirectory
                 where backupFilename is null
           fetch C1 into @C1_subdirectory;
        END
        close C1
        deallocate C1
        delete @RESTORE_headeronly where DatabaseName <> @databasename;
        /* 
        Produce script or execute depending of @execution_mode value
             1:Default. List All finded backupset
             2:Script      Verifyonly most recent backup sequence
             3:Script      Restore most recent backup sequence
             4:Execute     Verifyonly most recent backup sequence
             5:Execute     Restore most recent backup sequence
        */
        if @execution_mode = 1 /* 1:Default. List All finded backupset */
           begin
              select 
                    backupFilename     ,BackupType             ,position             ,ServerName
                   ,DatabaseName       ,BackupStartDate        ,FirstLSN             ,LastLSN
                   ,DifferentialBaseLSN
                from @RESTORE_headeronly
                where BackupType in (1,2,5)
                order by BackupStartDate;
           end
        else 
        /*   2:Script      Verifyonly most recent backup sequence
             3:Script      Restore most recent backup sequence
             4:Execute     Verifyonly most recent backup sequence
             5:Execute     Restore most recent backup sequence
        */
          begin
              declare @backup table
                    ( Sql#                    int
                    , Backup_entry            int
                    , DatabaseName            nvarchar(128)
                    , backupFilename          nvarchar(512)
                    , BackupType              smallint
                    , Position                smallint
                    , ServerName              nvarchar(512)
                    , BackupStartDate         datetime
                    , BackupFinishDate        datetime
                    , FirstLSN                numeric(25, 0)
                    , LastLSN                 numeric(25, 0)
                    , DifferentialBaseLSN     numeric(25, 0)
                    );
              with
               LastBkpFull as 
                 (select top 1
                        1 as sql#, R.Backup_entry, R.DatabaseName, r.backupFilename, r.BackupType, r.Position, r.ServerName, r.BackupStartDate, r.BackupFinishDate
                        , r.FirstLSN, r.LastLSN, r.DifferentialBaseLSN
                  from @RESTORE_headeronly as R
                  where R.BackupType = 1
                  order by R.BackupStartDate desc
                 )
              ,LastBkpDiff as
                 (select top 1 
                        2 as sql#, R.Backup_entry, R.DatabaseName, r.backupFilename, r.BackupType, r.Position, r.ServerName, r.BackupStartDate, r.BackupFinishDate
                        , r.FirstLSN, r.LastLSN, r.DifferentialBaseLSN
                  from @RESTORE_headeronly as R
                  where R.BackupType = 5
                  and DifferentialBaseLSN = (select FirstLSN from LastBkpFull)
                  order by R.BackupStartDate desc
                 )
              ,LastBkpDB as
                 (select top 1 *
                  from (select *  from LastBkpFull 
                        union all
                       select * from LastBkpDiff) as BckDB
                  order by BackupStartDate desc
                 )
              ,BckLogSerie as
                 (select top 1 (select sql# from LastBkpDB) +1 as sql#
                        , R.Backup_entry, R.DatabaseName, r.backupFilename, r.BackupType, r.Position, r.ServerName, r.BackupStartDate, r.BackupFinishDate
                        , r.FirstLSN, r.LastLSN, r.DifferentialBaseLSN
                  from @RESTORE_headeronly as R
                  where r.BackupType = 2
                  and r.LastLSN > (select FirstLSN from LastBkpDB)
                  order by r.BackupStartDate asc
                 Union ALL
                  Select BLS.sql#+1
                           , R.Backup_entry, R.DatabaseName, r.backupFilename, r.BackupType, r.Position, r.ServerName, r.BackupStartDate, r.BackupFinishDate
                        , r.FirstLSN, r.LastLSN, r.DifferentialBaseLSN 
                  from BckLogSerie as BLS
                    inner join @RESTORE_headeronly as R 
                        on BLS.LastLSN=R.FirstLSN
                  where r.BackupType = 2
                 )
              insert into @backup
                 select * from LastBkpFull
                 union all
                 select * from LastBkpDiff
                 union all
                 select * from BckLogSerie
              Declare @RestoreFilelist as table
                    (LogicalName             nvarchar(128)
                    ,PhysicalName            nvarchar(260)
                    ,Type                    char(1)
                    ,FileGroupName           nvarchar(128) NULL
                    ,Size                    numeric(20,0)
                    ,MaxSize                 numeric(20,0)
                    ,FileID                  bigint
                    ,CreateLSN               numeric(25,0)
                    ,DropLSN                 numeric(25,0) NULL
                    ,DUniqueID               uniqueidentifier
                    ,ReadOnlyLSN             numeric(25,0) NULL
                    ,ReadWriteLSN            numeric(25,0) NULL
                    ,BackupSizeInBytes       bigint
                    ,SourceBlockSize         Int
                    ,FileGroupID             Int
                    ,LogGroupGUID            uniqueidentifier NULL
                    ,DifferentialBaseLSN     numeric(25,0) NULL
                    ,DifferentialBaseGUID    uniqueidentifier NULL
                    ,IsReadOnly              bit
                    ,IsPresent               bit
                    ,TDEThumbprint           varbinary(32) NULL
                    ,SnapshotURL             nvarchar(360) NULL
                    );
              select @STR_SQL = 'Restore filelistOnly from disk = ''' 
                              + @Backup_Path_Folder+char(92)+ backupFilename
                              +''' with file =' + convert(varchar(2), Position)
                 from @backup
                 where Sql# =1
              insert into @RestoreFilelist
                 exec(@str_sql);
              declare @Move_to               varchar(max) =''
              select @Move_to = @Move_to 
                           + ', Move ''' 
                           + LogicalName
                           + ''' to '''
                           + case  when Type = 'L' then
                                     IIF(@Restore_Logfile_Folder is null        
                                         , PhysicalName
                                         , @Restore_Logfile_Folder 
                                            + Right (PhysicalName, charindex(char(92),reverse(physicalname)))
                                        )
                                 else
                                    IIF(@Restore_Datafile_Folder is null        
                                                        , PhysicalName
                                                        , @Restore_Datafile_Folder 
                                                           + Right (PhysicalName, charindex(char(92),reverse(physicalname))))
                                 end 
                           + ''''
                 from @RestoreFilelist
              Declare @Result_Set table
                 (sql#                      int
                 ,Backup_entry              int
                 ,BackupStartDate           datetime
                 ,Sql_command               varchar(max)
                 ,DatabaseName              varchar(250)
                 )
              insert into @Result_Set
                select sql#
                   , Backup_entry
                   , BackupStartDate
                        /* @Execution_Mode  
                           2:Script      Verifyonly most recent backup sequence
                           3:Script      Restore most recent backup sequence
                           4:Execute     Verifyonly most recent backup sequence
                           5:Execute     Restore most recent backup sequence
                      */
                   , case when @Execution_Mode in (2,4) then 'restore verifyonly from disk ='''
                          when @Execution_Mode in (3,5) then 'restore '
                                                          + IIF(BackupType = 2,'Log ','Database ')
                                                          + DatabaseName
                                                          + ' from disk ='''
                          else null
                      end
                     + @Backup_Path_Folder+char(92)+ backupFilename
                                +''' with file =' + convert(varchar(2), Position)
                     + @Move_to        
                     + iif(@Execution_Mode in (3,5),', NORECOVERY','')
                     As Sql_Command    
                   ,DatabaseName 
                  from @backup
                  order by sql# asc
              if @Execution_Mode in (2,3)
                 select * from @Result_Set
              else
                begin
                  declare @recovery            varchar(max)
                  declare C2 cursor for select SQL_command from @Result_Set
                  open C2
                  fetch c2 into @STR_SQL
                  while @@fetch_Status = 0
                    BEGIN
                       Print 'Executing : ' + @STR_SQL
                       execute (@STR_SQL)
                       fetch c2 into @STR_SQL
                    END
                  close C2
                  deallocate C2
                  if @Execution_Mode = 5
                 begin
                 set @recovery = 'Restore database '+ @databasename + ' with recovery'
                 execute (@recovery)
                 end
                end
          end
        return 0
    end
    Enjoy
    Le savoir est une nourriture qui exige des efforts.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 571
    Points
    52 571
    Billets dans le blog
    5
    Par défaut
    Il y a juste un souci, c'est que les commandes RESTORE ... ONLY ne produisent pas le même nombre de colonnes en fonction des versions de SQL Server...

    Exemple dans RESTORE FILELISTONLY, les colonnes TDEThumbprint et SnapshotURL ne sont pas dans toutes les versions....

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    justement ça me casse les pieds de devoir gérer les versions.
    On pourrait dire que c'est un accès de flemme si on parle des versions antérieures mais c'est aussi pour envisager les versions futures.

    N'existe-t'il pas une écriture pour "stabiliser" ça ?
    Le savoir est une nourriture qui exige des efforts.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    On pourrait dire que c'est un accès de flemme si on parle des versions antérieures mais c'est aussi pour envisager les versions futures.
    Le bon mot est « EXCÈS de flemme » .

  5. #5
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 731
    Points : 1 416
    Points
    1 416
    Par défaut
    Le savoir est une nourriture qui exige des efforts.

Discussions similaires

  1. Restauration sur un serveur à partir d'un bak sur poste
    Par Jean-Philippe André dans le forum MS SQL Server
    Réponses: 11
    Dernier message: 06/06/2012, 12h09
  2. Réponses: 2
    Dernier message: 22/01/2010, 16h26
  3. [WSS 2007] Restauration sur un serveur avec Nom différent
    Par wil4linux dans le forum SharePoint
    Réponses: 9
    Dernier message: 10/07/2007, 14h07
  4. Erreur apres restauration d'une base sur nouveau serveur
    Par tribune dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 03/02/2006, 15h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo