sql >> Base de Datos >  >> RDS >> Database

Un procedimiento almacenado dedicado para obtener el último estado de las copias de seguridad de la base de datos

Cualquier DBA de SQL Server (por supuesto, esto se aplica a todas las plataformas) estará de acuerdo en que las copias de seguridad de la base de datos son las cosas más esenciales para los profesionales de datos. Monitorear los estados de esas copias de seguridad es crucial. Para que esta tarea sea más sencilla, he creado un procedimiento almacenado personalizado. Le permitirá obtener los estados de las últimas copias de seguridad de la base de datos (si las hay) para todas las bases de datos necesarias bajo su cuidado.

Antes de comenzar, verifique la cuenta que ejecuta este procedimiento almacenado. Debe tener los derechos necesarios para realizar SELECT en las siguientes tablas para crear el procedimiento almacenado:

  • sys.bases de datos (maestro)
  • familia de medios de copia de seguridad (msdb)
  • conjunto de copia de seguridad (msdb)

Cómo usar el procedimiento almacenado

El código T-SQL del procedimiento almacenado se proporciona en este artículo. El procedimiento espera 2 parámetros:

  • @base de datos es el nombre de la base de datos de destino. Si no se especifica ninguna, se asumirán todas las bases de datos.
  • @backupType es el tipo de copia de seguridad que desea comprobar. Dependiendo de su situación, puede ser:
    • F – Completo
    • D – Diferencial
    • L – Registro de transacciones
    • A – Todo lo anterior

Aquí hay una matriz de posibles combinaciones de parámetros que se pueden usar y el resultado que debe esperar. X es el nombre de la base de datos a la que desea apuntar.

@base de datos @backupType Salida
Todos A Muestra las copias de seguridad completas, diferenciales y de registro de transacciones más recientes de todas las bases de datos dentro de la instancia.
Todos F Muestra las copias de seguridad completas más recientes de todas las bases de datos dentro de la instancia.
Todos D Muestra las copias de seguridad diferenciales más recientes de todas las bases de datos dentro de la instancia.
Todos L Muestra las copias de seguridad del registro de transacciones más recientes de todas las bases de datos dentro de la instancia.
X A Muestra las copias de seguridad completas, diferenciales y de registro de transacciones más recientes de la base de datos X dentro de la instancia.
X F Muestra la copia de seguridad completa más reciente de la base de datos X dentro de la instancia.
X D Muestra la copia de seguridad diferencial más reciente de la base de datos X dentro de la instancia.
X L Muestra la copia de seguridad del registro de transacciones más reciente de la base de datos X dentro de la instancia.

Nota :si la base de datos de destino está en el modelo de recuperación simple, la información de las copias de seguridad del registro de transacciones aparecerá como NULL. Nunca ha estado bajo el modelo de recuperación completa y nunca se ha realizado la copia de seguridad del registro de transacciones.

Pruebas de ejecución

Voy a demostrar algunas de las combinaciones de secuencias de comandos para que tenga una idea de qué esperar de este procedimiento almacenado:

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'

Las capturas de pantalla no cubrirán el SP dirigido a una sola base de datos porque el resultado es el mismo, la única diferencia es que muestra una base de datos.

Como puede ver, los datos de las columnas "Diferencial" son NULL porque nunca hice una copia de seguridad diferencial para ninguno de ellos. Sin embargo, para demostrar completamente cuán útil puede ser esta solución, necesitamos una copia de seguridad diferencial. Tomaré uno para la base de datos DBA y ejecutaré el Procedimiento almacenado para ver qué devuelve:

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

Después de realizar la copia de seguridad diferencial, puede ver que nuestro procedimiento almacenado también devuelve los datos para las columnas diferenciales, precisamente de la copia de seguridad que acabo de hacer.

El código de procedimiento almacenado completo

Al comienzo de la secuencia de comandos, verá los valores predeterminados:la secuencia de comandos los asume si no se pasa ningún valor para cada parámetro.

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

Conclusión

Con este procedimiento almacenado personalizado, puede crear un mecanismo que le avise cuando no se haya realizado un determinado tipo de copia de seguridad para una base de datos determinada en un período determinado.

Puede implementar este procedimiento almacenado en cada instancia de SQL Server y comprobar la información de las copias de seguridad de cada base de datos (bases de datos del sistema y del usuario).

Además, puede utilizar la información devuelta por el procedimiento almacenado para crear un mapa de copias de seguridad para identificar la ubicación del archivo de copia de seguridad más reciente para cada base de datos. En mi trabajo actual, he usado esto para crear un script para orquestar las pruebas de restauración de todas las copias de seguridad bajo mi soporte y confirmar que son 100 % confiables. Para mí, ha sido extremadamente útil.