Database
 sql >> Base de données >  >> RDS >> Database

Une procédure stockée dédiée pour obtenir le dernier état des sauvegardes de base de données

Tout administrateur de base de données SQL Server (bien sûr, cela s'applique à toutes les plates-formes) conviendra que les sauvegardes de bases de données sont les choses les plus essentielles pour les professionnels des données. La surveillance des statuts de ces sauvegardes est cruciale. Pour simplifier cette tâche, j'ai créé une procédure stockée personnalisée. Cela vous permettra d'obtenir les derniers statuts des sauvegardes de base de données (le cas échéant) pour toutes les bases de données nécessaires dont vous avez la charge.

Avant de commencer, vérifiez le compte exécutant cette procédure stockée. Il doit avoir les droits nécessaires pour effectuer SELECT sur les tables suivantes afin de créer la procédure stockée :

  • sys.databases (maître)
  • backupmediafamily (msdb)
  • sauvegarde (msdb)

Comment utiliser la procédure stockée

Le code T-SQL de procédure stockée est fourni dans cet article. La procédure attend 2 paramètres :

  • @base de données est le nom de la base de données cible. Si aucune n'est spécifiée, toutes les bases de données seront supposées.
  • @backupType est le type de sauvegarde que vous souhaitez vérifier. Selon votre situation, cela peut être :
    • F – Complète
    • D – Différentiel
    • L – Journal des transactions
    • Un – Tout ce qui précède

Voici une matrice des combinaisons de paramètres possibles qui peuvent être utilisées et la sortie à laquelle vous devez vous attendre. X est le nom de la base de données que vous souhaitez cibler.

@database @backupType Sortie
Tous A Affiche les sauvegardes complètes, différentielles et du journal des transactions les plus récentes de toutes les bases de données de l'instance.
Tous F Affiche les sauvegardes complètes les plus récentes de toutes les bases de données de l'instance.
Tous D Affiche les sauvegardes différentielles les plus récentes de toutes les bases de données de l'instance.
Tous L Affiche les sauvegardes les plus récentes du journal des transactions de toutes les bases de données de l'instance.
X A Affiche les sauvegardes complètes, différentielles et du journal des transactions les plus récentes de la base de données X au sein de l'instance.
X F Affiche la sauvegarde complète la plus récente de la base de données X dans l'instance.
X D Affiche la sauvegarde différentielle la plus récente de la base de données X dans l'instance.
X L Affiche la sauvegarde du journal des transactions la plus récente de la base de données X dans l'instance.

Remarque  :si la base de données cible est dans le modèle de récupération simple, les informations de sauvegarde du journal des transactions s'afficheront comme NULL. Il n'a jamais été sous le modèle de récupération complète et la sauvegarde du journal des transactions n'a jamais eu lieu pour lui.

Tests d'exécution

Je vais vous montrer certaines des combinaisons de scripts pour vous donner une idée de ce à quoi vous attendre de cette procédure stockée :

EXEC DBA_DatabaseBackups @database = 'All', @backupType = 'A'
EXEC DBA_DatabaseBackups @database = 'All', @backupType = 'F'
EXEC DBA_DatabaseBackups @database = 'All', @backupType = 'D'
EXEC DBA_DatabaseBackups @database = 'All', @backupType = 'L'

Les captures d'écran ne couvriront pas le SP ciblant une seule base de données car la sortie est la même, la seule différence est qu'elle affiche une seule base de données.

Comme vous pouvez le voir, les données des colonnes "Différentiel" sont NULL car je n'ai jamais fait de sauvegarde différentielle pour aucune d'entre elles. Cependant, pour démontrer pleinement l'utilité de cette solution, nous avons besoin d'une sauvegarde différentielle. Je vais en prendre un pour la base de données DBA et exécuter la procédure stockée pour voir ce qu'elle renvoie :

EXEC DBA_DatabaseBackups @database = 'DBA', @backupType = 'D'

Après avoir effectué la sauvegarde différentielle, vous pouvez voir que notre procédure stockée renvoie également les données des colonnes différentielles, précisément de la sauvegarde que je viens de faire.

Le code de procédure stockée complet

Au tout début du script, vous verrez des valeurs par défaut - le script les assume si aucune valeur n'est transmise pour chaque paramètre.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		Alejandro Cobar
-- Create date: 	2021-05-10
-- Description:	SP to retrieve the latest backups information
-- =============================================
CREATE PROCEDURE DBA_DatabaseBackups
	@database VARCHAR(256) = 'all', 
	@backupType CHAR(1) = 'A'
AS
BEGIN
	SET NOCOUNT ON;

	DECLARE @sqlCommand VARCHAR(MAX);

	SET @sqlCommand = '
    WITH MostRecentBackups
	AS(
		SELECT 
			database_name AS [Database],
			MAX(bus.backup_finish_date) AS LastBackupTime,
			CASE bus.type
				WHEN ''D'' THEN ''Full''
				WHEN ''I'' THEN ''Differential''
				WHEN ''L'' THEN ''Transaction Log''
			END AS Type
		FROM msdb.dbo.backupset bus
		WHERE bus.type <> ''F''
		GROUP BY bus.database_name,bus.type
	),
	BackupsWithSize
	AS(
		SELECT 
			mrb.*, 
			(SELECT TOP 1 CONVERT(DECIMAL(10,4), b.compressed_backup_size/1024/1024/1024) AS backup_size FROM msdb.dbo.backupset b WHERE [Database] = b.database_name AND LastBackupTime = b.backup_finish_date) AS [Backup Size],
			(SELECT TOP 1 DATEDIFF(s, b.backup_start_date, b.backup_finish_date) FROM msdb.dbo.backupset b WHERE [Database] = b.database_name AND LastBackupTime = b.backup_finish_date) AS [Seconds],
			(SELECT TOP 1 b.media_set_id FROM msdb.dbo.backupset b WHERE [Database] = b.database_name AND LastBackupTime = b.backup_finish_date) AS media_set_id
		FROM MostRecentBackups mrb
	)

	SELECT 
d.name AS [Database],
      	d.state_desc AS State,
      	d.recovery_model_desc AS [Recovery Model],'

	  IF @backupType = 'F' OR @backupType = 'A'
	  SET @sqlCommand += '
      bf.LastBackupTime AS [Last Full],
      DATEDIFF(DAY,bf.LastBackupTime,GETDATE()) AS [Time Since Last Full (in Days)],
      bf.[Backup Size] AS [Full Backup Size],
      bf.Seconds AS [Full Backup Seconds to Complete],
      (SELECT TOP 1 bmf.physical_device_name FROM msdb.dbo.backupmediafamily bmf WHERE bmf.media_set_id = bf.media_set_id AND bmf.device_type = 2) AS [Full Backup Path]
      '

	  IF @backupType = 'A'
	  SET @sqlCommand += ','

	  IF @backupType = 'D' OR @backupType = 'A'
	  SET @sqlCommand += '
	  bd.LastBackupTime AS [Last Differential],
      DATEDIFF(DAY,bd.LastBackupTime,GETDATE()) AS [Time Since Last Differential (in Days)],
      bd.[Backup Size] AS [Differential Backup Size],
      bd.Seconds AS [Diff Backup Seconds to Complete],
      (SELECT TOP 1 bmf.physical_device_name FROM msdb.dbo.backupmediafamily bmf WHERE bmf.media_set_id = bd.media_set_id AND bmf.device_type = 2) AS [Diff Backup Path]
      '

	  IF @backupType = 'A'
	  SET @sqlCommand += ','

	  IF @backupType = 'L' OR @backupType = 'A'
	  SET @sqlCommand += '
	  bt.LastBackupTime AS [Last Transaction Log],
      DATEDIFF(MINUTE,bt.LastBackupTime,GETDATE()) AS [Time Since Last Transaction Log (in Minutes)],
      bt.[Backup Size] AS [Transaction Log Backup Size],
      bt.Seconds AS [TLog Backup Seconds to Complete],
      (SELECT TOP 1 bmf.physical_device_name FROM msdb.dbo.backupmediafamily bmf WHERE bmf.media_set_id = bt.media_set_id AND bmf.device_type = 2) AS [Transaction Log Backup Path]
	  '

	SET @sqlCommand += '
	FROM sys.databases d
	LEFT JOIN BackupsWithSize bf ON (d.name = bf.[Database] AND (bf.Type = ''Full'' OR bf.Type IS NULL))
	LEFT JOIN BackupsWithSize bd ON (d.name = bd.[Database] AND (bd.Type = ''Differential'' OR bd.Type IS NULL))
	LEFT JOIN BackupsWithSize bt ON (d.name = bt.[Database] AND (bt.Type = ''Transaction Log'' OR bt.Type IS NULL))
	WHERE d.name <> ''tempdb'' AND d.source_database_id IS NULL'

	IF LOWER(@database) <> 'all'
	SET @sqlCommand += ' AND d.name ='+CHAR(39)[email protected]+CHAR(39)

	EXEC (@sqlCommand)
END
GO

Conclusion

Avec cette procédure stockée personnalisée, vous pouvez créer un mécanisme pour vous alerter lorsqu'un certain type de sauvegarde pour une base de données donnée n'a pas été effectuée au cours d'une période donnée.

Vous pouvez déployer cette procédure stockée dans chaque instance SQL Server et vérifier les informations de sauvegarde pour chaque base de données (bases de données système et utilisateur).

En outre, vous pouvez utiliser les informations renvoyées par la procédure stockée pour créer une carte de sauvegardes pour identifier l'emplacement du dernier fichier de sauvegarde pour chaque base de données. Dans mon travail actuel, j'ai utilisé cela pour créer un script pour orchestrer les tests de restauration de toutes les sauvegardes sous mon support et confirmer qu'elles sont fiables à 100 %. Pour moi, cela a été extrêmement utile.