sql >> Database teknologi >  >> RDS >> Database

En dedikeret lagret procedure for at få den seneste database-backup-status

Enhver SQL Server DBA (selvfølgelig gælder dette for alle platforme) vil være enige i, at backup af databaser er de mest essentielle ting for dataprofessionelle. Overvågning af disse sikkerhedskopiers status er afgørende. For at gøre denne opgave mere ligetil har jeg oprettet en tilpasset lagret procedure. Det giver dig mulighed for at få de seneste databasesikkerhedskopier (hvis nogen) statusser for alle de nødvendige databaser under din varetægt.

Før vi starter, skal du kontrollere kontoen, der udfører denne lagrede procedure. Det skal have de nødvendige rettigheder til at udføre SELECT på følgende tabeller for at oprette den lagrede procedure:

  • sys.databases (master)
  • backupmediafamily (msdb)
  • backupset (msdb)

Sådan bruges den lagrede procedure

Den Stored Procedure T-SQL-kode findes i denne artikel. Proceduren forventer 2 parametre:

  • @database er navnet på måldatabasen. Hvis ingen er angivet, vil alle databaser blive antaget.
  • @backupType er den type sikkerhedskopi, du vil kontrollere. Afhængigt af din situation kan det være:
    • F – Fuld
    • D – Differential
    • L – Transaktionslog
    • A – Alt ovenstående

Her er en matrix af mulige parameterkombinationer, der kan bruges, og det output, du bør forvente. X er navnet på den database, du vil målrette mod.

@database @backupType Output
Alle A Viser de seneste fuld-, differentiale- og transaktionslog-sikkerhedskopier af alle databaser i instansen.
Alle F Viser de seneste fulde sikkerhedskopier af alle databaser i instansen.
Alle D Viser de seneste differentielle sikkerhedskopier af alle databaser i instansen.
Alle L Viser de seneste transaktionslog-sikkerhedskopier af alle databaser i instansen.
X A Viser de seneste fuld-, differentiale- og transaktionslog-sikkerhedskopier af X-databasen i instansen.
X F Viser den seneste fulde backup af X-databasen i instansen.
X D Viser den seneste differentielle backup af X-databasen i instansen.
X L Viser den seneste sikkerhedskopi af transaktionslog af X-databasen i forekomsten.

Bemærk :Hvis måldatabasen er i Simple Recovery Model, vil transaktionslog-sikkerhedskopioplysningerne blive vist som NULL. Den har aldrig været under den fulde gendannelsesmodel, og sikkerhedskopieringen af ​​transaktionsloggen har aldrig fundet sted for den.

Udførelsestest

Jeg vil demonstrere nogle af scriptkombinationerne for dig for at få en idé om, hvad du kan forvente af denne lagrede procedure:

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'

Skærmbillederne vil ikke dække den SP, der er målrettet mod en enkelt database, fordi outputtet er det samme, den eneste forskel er, at den viser én database.

Som du kan se, er dataene for "Differential"-kolonnerne NULL, fordi jeg aldrig har lavet en differentiel backup for nogen af ​​dem. Men for fuldt ud at demonstrere, hvor nyttig denne løsning kan være, har vi brug for en differentiel backup. Jeg tager en til DBA-databasen og udfører den lagrede procedure for at se, hvad den returnerer:

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

Efter at have taget den differentielle sikkerhedskopi, kan du se, at vores lagrede procedure også returnerer dataene for differentielle kolonner, præcis af den sikkerhedskopi, jeg lige har lavet.

Den komplette kode for lagret procedure

Allerede i begyndelsen af ​​scriptet vil du se standardværdier – scriptet antager dem, hvis der ikke sendes nogen værdi for hver parameter.

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

Konklusion

Med denne brugerdefinerede lagrede procedure kan du bygge en mekanisme til at advare dig, når en bestemt sikkerhedskopieringstype for en given database ikke er blevet lavet inden for en bestemt periode.

Du kan implementere denne lagrede procedure i hver SQL Server-instans og kontrollere sikkerhedskopieringsoplysningerne for hver enkelt database (system- og brugerdatabaser).

Du kan også bruge informationen, der returneres af den lagrede procedure, til at bygge et sikkerhedskopikort for at identificere placeringen af ​​den seneste sikkerhedskopifil for hver database. I mit nuværende job har jeg brugt dette til at bygge et script til at orkestrere gendannelsestesten af ​​alle sikkerhedskopier under min support og bekræfte, at de er 100 % pålidelige. For mig har det været yderst nyttigt.


  1. Sådan rettes "EXECUTE-sætningen mislykkedes, fordi dens WITH RESULT SETS-klausul specificerede 1 resultatsæt(er)..." i SQL Server

  2. Vælg xml-elementværdi i Oracle

  3. Sådan tjekker du gammel statistik

  4. Sådan fungerer SQLite Avg()