USE [HCITools] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[bkp_Archive]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[bkp_Archive] GO USE [HCITools] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[bkp_Archive] @in_debug int = null, @in_Recovery_Model varchar(25) = null AS /*============================================================================= Explication du traitement realise par la SP ------------------------------------------- Cette SP sert à archiver les backups des bases de données en fonction du paramètre BKP_FRQ contenu dans la table HCI_PARAMS L'archivage se fait sur 3 jours glissant puis en fonction du choix, sur 30 jours et 60 jours Contexte d'utilisation ---------------------- Cette SP est appelée par les jobs D91010 - Backup of several databases D91040 - Backup of simple databases D91050 - Backup of full databases Parametres ---------- @in_debug : non utilisé pour le moment Creation : 06.10.15 / FLA Modifications : 14.09.16 / FLA Remplacement des xp_cmdshell par la CLR Ajout de la gestion des erreurs de chaque step Ajout de la gestion de l'archivage uniquement des bases backupées 15.09.16 / FLA Séléction uniquement des bases de données online 24.05.17 / FLA Ajout du choix du mode de recovery des bases pour archiver leur backup 17.03.22 / FLA Change DBA mail =============================================================================*/ set nocount on; declare @result_sp int, @errno int, @errmsg varchar(255) /*------------------- Declaration des variables --------------------*/ declare @NbError int, @TypeArchive int, @BackupFolder varchar (4000), @BackupFolderA varchar (4000), @OldPath varchar (4000), @NewPath varchar (4000), @Path varchar (4000), @messageError varchar (max), @messageToSend varchar(8000), @xml xml, @delimiter varchar(1), @param_group_counter_list nvarchar(3000), @name varchar (255) /*------------ Affectation des parametres aux variables ------------*/ SELECT @TypeArchive=HCIP_value FROM dbo.HCI_PARAMS WHERE HCIP_key = 'BKP_FRQ' ; SELECT @BackupFolder=HCIP_value FROM dbo.HCI_PARAMS WHERE HCIP_key = 'BKP_DIR' ; SELECT @BackupFolderA=HCIP_value FROM dbo.HCI_PARAMS WHERE HCIP_key = 'BKP_DIR_A' ; SELECT @param_group_counter_list = HCIP_value FROM dbo.HCI_PARAMS WHERE HCIP_key = 'BKP_NOT_DB' ; IF @in_Recovery_Model is null SET @in_Recovery_Model = 'FULL,SIMPLE,BULK-LOGGED' SET @delimiter = ',' SET @xml = CAST((''+REPLACE(@param_group_counter_list, @delimiter, '')+''+''+REPLACE(@in_Recovery_Model, @delimiter, '')+'') AS XML) set @NbError = 0 set @messageError = '' if @TypeArchive is null or @BackupFolder is null or @BackupFolderA is null or @param_group_counter_list is null begin select @errno = 70003, @errmsg = '(BKP) Paramètres BKP_FRQ ou BKP_DIR ou BKP_DIR_A ou BKP_NOT_DB non initialisé dans HCI_PARAMS !' goto error_99 end /*-------------------------- Traitement ---------------------------*/ IF @TypeArchive <> 0 BEGIN /* ON PARCOURT TOUTES LES BASES */ declare c_databases cursor local forward_only static for SELECT name FROM sys.databases WHERE LOWER(name) not in (SELECT C.value('.', 'varchar(3000)') AS value FROM @xml.nodes('X') AS X(C)) AND state = 0 AND recovery_model_desc IN (SELECT C.value('.', 'varchar(3000)') AS value FROM @xml.nodes('Y') AS X(C)) ORDER BY name ; open c_databases ; FETCH NEXT FROM c_databases into @name ; while @@fetch_status <> -1 begin if @@fetch_status <> -2 begin /* ARCHIVE */ /* MOVE LAST DUMP FOR ARCHIVING */ BEGIN TRY SET @OldPath = @BackupFolder + @name + '_Dump.bak' SET @NewPath = @BackupFolderA + @name + '_Dump.bak' exec dbo.aps_File_Move @OldPath, @NewPath END TRY BEGIN CATCH select @messageError = @messageError + 'Move last backup for archiving failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH /* DELETE OLDEST DUMP, OR ARCHIVE AS MONTHLY DUMP */ if datepart (dd, getdate()) > 7 or datepart (weekday, getdate()) <> datepart (weekday, '2013-01-01') /* '2013-01-01' was a Tuesday */ begin /* DELETE OLDEST ARCHIVED DUMP */ BEGIN TRY SET @Path = @BackupFolderA + @name + '_Dump_3.bak' exec dbo.aps_File_Delete @Path END TRY BEGIN CATCH select @messageError = @messageError + 'Delete oldest archived backup failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH end else begin /* IN THE FIRST TUESDAY OF THE MONTH, THE MONTHLY DUMP IS UPDATED */ IF @TypeArchive = 330 BEGIN /* DELETE MONTHLY DUMP */ BEGIN TRY SET @Path = @BackupFolderA + @name + '_Dump_30.bak' exec dbo.aps_File_Delete @Path END TRY BEGIN CATCH select @messageError = @messageError + 'Delete monthly backup failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH END ELSE IF @TypeArchive = 33060 BEGIN /* DELETE MONTHLY DUMP 60 */ BEGIN TRY SET @Path = @BackupFolderA + @name + '_Dump_60.bak' exec dbo.aps_File_Delete @Path END TRY BEGIN CATCH select @messageError = @messageError + 'Delete monthly backup 60 failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH /* RENAME TO MONTHLY DUMP 30 TO 60 */ BEGIN TRY SET @OldPath = @BackupFolderA + @name + '_Dump_30.bak' SET @NewPath = @BackupFolderA + @name + '_Dump_60.bak' exec dbo.aps_File_Move @OldPath, @NewPath END TRY BEGIN CATCH select @messageError = @messageError + 'Rename to monthly backup 30 TO 60 failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH END BEGIN TRY SET @OldPath = @BackupFolderA + @name + '_Dump_3.bak' SET @NewPath = @BackupFolderA + @name + '_Dump_30.bak' exec dbo.aps_File_Move @OldPath, @NewPath END TRY BEGIN CATCH select @messageError = @messageError + 'Rename to monthly backup 3 to 30 failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH END ; /* RENAME ARCHIVED DUMPS */ BEGIN TRY SET @OldPath = @BackupFolderA + @name + '_Dump_2.bak' SET @NewPath = @BackupFolderA + @name + '_Dump_3.bak' exec dbo.aps_File_Move @OldPath, @NewPath END TRY BEGIN CATCH select @messageError = @messageError + 'Rename archived backup 2 to 3 failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH BEGIN TRY SET @OldPath = @BackupFolderA + @name + '_Dump_1.bak' SET @NewPath = @BackupFolderA + @name + '_Dump_2.bak' exec dbo.aps_File_Move @OldPath, @NewPath END TRY BEGIN CATCH select @messageError = @messageError + 'Rename archived backup 1 to 2 failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH BEGIN TRY SET @OldPath = @BackupFolderA + @name + '_Dump.bak' SET @NewPath = @BackupFolderA + @name + '_Dump_1.bak' exec dbo.aps_File_Move @OldPath, @NewPath END TRY BEGIN CATCH select @messageError = @messageError + 'Rename archived backup to 1 failed : ' + @name + ' ' + ERROR_MESSAGE() + CHAR(13) SET @NbError = @NbError + 1 END CATCH end /* if @@fetch_status <> -2 */ ; FETCH NEXT FROM c_databases into @name ; end /* while @@fetch_status <> -1 */ ; close c_databases ; deallocate c_databases ; if @NbError > 0 BEGIN SET @messageToSend = SUBSTRING(@messageError,0,8000); exec aps_Send_Mail_with_template @in_param_varchar_2 = 'DBA_operator;', @in_job_type = 3, /* 3 = warning */ @in_param_varchar_3 = @messageError ; select @errno = 70003, @errmsg = '(BKP) Erreur lors du job d''archivage' END END ; /*------------------ Retour au programme appelant -----------------*/ return(@@error); /*---------------------- Traitement des erreurs ----------------------*/ error_99: raiserror (@errmsg, 16, 1); return(@errno); GO