Każdy administrator bazy danych SQL Server (oczywiście dotyczy to wszystkich platform) zgodzi się, że tworzenie kopii zapasowych baz danych jest najważniejszą rzeczą dla profesjonalistów zajmujących się danymi. Monitorowanie statusów tych kopii zapasowych ma kluczowe znaczenie. Aby uprościć to zadanie, stworzyłem niestandardową procedurę składowaną. Pozwoli ci to uzyskać najnowsze statusy kopii zapasowych baz danych (jeśli istnieją) dla wszystkich niezbędnych baz danych pod Twoją opieką.
Zanim zaczniemy, sprawdź konto wykonujące tę procedurę składowaną. Musi mieć niezbędne uprawnienia do wykonania WYBORU w następujących tabelach, aby utworzyć procedurę składowaną:
- sys.bazy danych (główne)
- rodzina kopii zapasowych (msdb)
- zestaw kopii zapasowej (msdb)
Jak korzystać z procedury zapisanej
Kod T-SQL procedury składowanej znajduje się w tym artykule. Procedura wymaga 2 parametrów:
- @baza danych to nazwa docelowej bazy danych. Jeśli żadna nie zostanie określona, zostaną przyjęte wszystkie bazy danych.
- @backupType to typ kopii zapasowej, który chcesz sprawdzić. W zależności od sytuacji może to być:
- F – Pełna
- D – Dyferencjał
- L – Dziennik transakcji
- A – Wszystkie powyższe
Oto macierz możliwych kombinacji parametrów, których można użyć, oraz dane wyjściowe, których należy się spodziewać. X to nazwa bazy danych, na którą chcesz kierować reklamy.
@baza danych | @backupType | Wyjście |
Wszystkie | A | Wyświetla najnowsze kopie zapasowe pełnych, różnicowych i dziennika transakcji wszystkich baz danych w instancji. |
Wszystkie | F | Wyświetla najnowsze pełne kopie zapasowe wszystkich baz danych w instancji. |
Wszystkie | D | Wyświetla najnowsze różnicowe kopie zapasowe wszystkich baz danych w instancji. |
Wszystkie | L | Wyświetla najnowsze kopie zapasowe dziennika transakcji wszystkich baz danych w instancji. |
X | A | Wyświetla najnowsze kopie zapasowe pełnych, różnicowych i dziennika transakcji bazy danych X w instancji. |
X | F | Wyświetla najnowszą pełną kopię zapasową bazy danych X w instancji. |
X | D | Wyświetla najnowszą różnicową kopię zapasową bazy danych X w instancji. |
X | L | Wyświetla najnowszą kopię zapasową dziennika transakcji bazy danych X w instancji. |
Uwaga :Jeśli docelowa baza danych jest w prostym modelu odzyskiwania, informacje o kopiach zapasowych dziennika transakcji będą wyświetlane jako NULL. Nigdy nie był objęty modelem pełnego odzyskiwania i nigdy nie wykonano dla niego kopii zapasowej dziennika transakcji.
Testy wykonania
Zademonstruję niektóre kombinacje skryptów, aby zorientować się, czego można się spodziewać po tej procedurze składowanej:
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'
Zrzuty ekranu nie obejmują SP ukierunkowanego na pojedynczą bazę danych, ponieważ dane wyjściowe są takie same, jedyną różnicą jest to, że wyświetla jedną bazę danych.
Jak widać, dane dla kolumn „Differential” mają wartość NULL, ponieważ nigdy nie wykonałem różnicowej kopii zapasowej dla żadnej z nich. Aby jednak w pełni zademonstrować, jak przydatne może być to rozwiązanie, potrzebujemy kopii różnicowej. Wezmę jeden do bazy danych DBA i wykonam procedurę składowaną, aby zobaczyć, co zwraca:
EXEC DBA_DatabaseBackups @database = 'DBA', @backupType = 'D'
Po wykonaniu różnicowej kopii zapasowej widać, że nasza procedura składowana zwraca również dane dla kolumn różnicowych, dokładnie z kopii zapasowej, którą właśnie utworzyłem.
Kompletny kod procedury składowanej
Na samym początku skryptu zobaczysz wartości domyślne – skrypt przyjmuje je, jeśli nie przekazano żadnej wartości dla każdego parametru.
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
Wniosek
Dzięki tej niestandardowej procedurze przechowywanej możesz zbudować mechanizm ostrzegający, gdy określony typ kopii zapasowej dla dowolnej bazy danych nie został wykonany w określonym czasie.
Możesz wdrożyć tę procedurę składowaną w każdym wystąpieniu programu SQL Server i sprawdzić informacje o kopiach zapasowych dla każdej pojedynczej bazy danych (bazy danych systemu i użytkowników).
Możesz także użyć informacji zwróconych przez procedurę składowaną do zbudowania mapy kopii zapasowych aby określić lokalizację najnowszego pliku kopii zapasowej dla każdej bazy danych. W mojej obecnej pracy wykorzystałem to do zbudowania skryptu do organizowania testów przywracania wszystkich kopii zapasowych objętych moim wsparciem i potwierdzania, że są one w 100% niezawodne. Dla mnie było to niezwykle przydatne.