Alla SQL Server DBA (naturligtvis, detta gäller alla plattformar) kommer att hålla med om att säkerhetskopiering av databas är det viktigaste för dataproffs. Det är avgörande att övervaka dessa säkerhetskopior. För att göra den här uppgiften enklare har jag skapat en anpassad lagrad procedur. Det gör att du kan få de senaste databassäkerhetskopiornas (om några) statusar för alla nödvändiga databaser under din vård.
Innan vi börjar, kontrollera kontot som kör denna lagrade procedur. Den måste ha de nödvändiga rättigheterna för att utföra SELECT i följande tabeller för att skapa den lagrade proceduren:
- sys.databases (master)
- backupmediafamily (msdb)
- säkerhetskopiering (msdb)
Hur man använder den lagrade proceduren
T-SQL-koden för lagrad procedur finns i den här artikeln. Proceduren förväntar sig två parametrar:
- @databas är namnet på måldatabasen. Om ingen anges kommer alla databaser att antas.
- @backupType är den typ av säkerhetskopia du vill kontrollera. Beroende på din situation kan det vara:
- F – Full
- D – Differential
- L – Transaktionslogg
- A – Allt ovan
Här är en matris med möjliga parameterkombinationer som kan användas, och den utdata du kan förvänta dig. X är namnet på databasen du vill rikta in dig på.
@databas | @backupType | Utdata |
Alla | A | Visar de senaste säkerhetskopiorna av fullständig, differentiell och transaktionslogg av alla databaser i instansen. |
Alla | F | Visar de senaste fullständiga säkerhetskopiorna av alla databaser i instansen. |
Alla | D | Visar de senaste differentiella säkerhetskopiorna av alla databaser i instansen. |
Alla | L | Visar de senaste säkerhetskopiorna av transaktionsloggar av alla databaser i instansen. |
X | A | Visar de senaste säkerhetskopiorna av fullständig, differentiell och transaktionslogg av X-databasen i instansen. |
X | F | Visar den senaste fullständiga säkerhetskopian av X-databasen i instansen. |
X | D | Visar den senaste differentiella säkerhetskopian av X-databasen i instansen. |
X | L | Visar den senaste säkerhetskopian av transaktionsloggen av X-databasen i instansen. |
Obs :Om måldatabasen är i Simple Recovery Model, kommer informationen om transaktionsloggen att visas som NULL. Den har aldrig varit under modellen för fullständig återställning, och säkerhetskopieringen av transaktionsloggen har aldrig ägt rum för den.
Utförandetester
Jag kommer att demonstrera några av skriptkombinationerna för att du ska få en uppfattning om vad du kan förvänta dig av denna lagrade procedur:
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ärmbilderna kommer inte att täcka SP som riktar sig till en enskild databas eftersom utdata är densamma, den enda skillnaden är att den visar en databas.
Som du kan se är data för "Differential"-kolumnerna NULL eftersom jag aldrig har gjort en differentiell säkerhetskopia för någon av dem. Men för att till fullo visa hur användbar den här lösningen kan vara behöver vi en differentiell backup. Jag tar en för DBA-databasen och kör den lagrade proceduren för att se vad den returnerar:
EXEC DBA_DatabaseBackups @database = 'DBA', @backupType = 'D'
Efter att ha tagit den differentiella säkerhetskopian kan du se att vår lagrade procedur även returnerar data för differentialkolumner, exakt av säkerhetskopian jag just har gjort.
Den kompletta lagrade procedurkoden
Allra i början av skriptet kommer du att se standardvärden – skriptet antar dem om inget värde skickas för varje 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
Slutsats
Med denna anpassade lagrade procedur kan du bygga en mekanism för att varna dig när en viss säkerhetskopieringstyp för en viss databas inte har gjorts inom en viss period.
Du kan distribuera denna lagrade procedur i varje SQL Server-instans och kontrollera säkerhetskopieringsinformationen för varje enskild databas (system- och användardatabaser).
Du kan också använda informationen som returneras av den lagrade proceduren för att bygga en säkerhetskopiakarta för att identifiera platsen för den senaste säkerhetskopian för varje databas. I mitt nuvarande jobb har jag använt detta för att bygga ett skript för att organisera återställningstesten av alla säkerhetskopior under mitt stöd och bekräfta att de är 100% tillförlitliga. För mig har det varit oerhört användbart.