Всеки SQL Server DBA (разбира се, това важи за всички платформи) ще се съгласи, че архивирането на база данни е най-важното нещо за професионалистите по данни. Наблюдението на състоянието на тези архивни копия е от решаващо значение. За да направя тази задача по-лесна, създадох персонализирана Съхранена процедура. Това ще ви позволи да получите статуса на най-новите архивни копия на база данни (ако има такива) за всички необходими бази данни, за които се грижите.
Преди да започнем, проверете акаунта, изпълняващ тази Съхранена процедура. Той трябва да има необходимите права за извършване на SELECT на следните таблици, за да създаде съхранената процедура:
- sys.databases (главен)
- backupmediafamily (msdb)
- резервно копие (msdb)
Как да използвате съхранената процедура
T-SQL кодът на съхранената процедура е предоставен в тази статия. Процедурата очаква 2 параметъра:
- @database е името на целевата база данни. Ако не е посочена нито една, ще се приемат всички бази данни.
- @backupType е типът резервно копие, което искате да проверите. В зависимост от вашата ситуация, това може да бъде:
- F – Пълен
- D – Диференциал
- L – Регистър на транзакциите
- A – Всичко по-горе
Ето матрица от възможни комбинации от параметри, които могат да се използват, и изхода, който трябва да очаквате. X е името на базата данни, към която искате да насочите.
@database | @backupType | Изход |
Всички | A | Показва най-новите пълни, диференциални и регистрационни копия на транзакциите на всички бази данни в екземпляра. |
Всички | F | Показва най-новите Пълни резервни копия на всички бази данни в екземпляра. |
Всички | D | Показва най-новите диференциални архиви на всички бази данни в екземпляра. |
Всички | L | Показва най-новите архивни копия на регистрационния файл на транзакциите на всички бази данни в екземпляра. |
X | A | Показва най-новите пълни, диференциални и регистрационни копия на транзакциите на базата данни X в рамките на екземпляра. |
X | F | Показва най-новото пълно архивиране на базата данни X в рамките на екземпляра. |
X | D | Показва най-новото диференциално архивиране на базата данни X в рамките на екземпляра. |
X | L | Показва най-новото архивиране на регистрационния файл на транзакциите на базата данни X в рамките на екземпляра. |
Забележка :Ако целевата база данни е в прост модел за възстановяване, информацията за архивиране на регистрационния файл на транзакциите ще се покаже като NULL. Никога не е бил под модела за пълно възстановяване и архивирането на регистрационния файл на транзакциите никога не се е извършвало за него.
Тестове за изпълнение
Ще ви демонстрирам някои от комбинациите от скриптове, за да получите представа какво да очаквате от тази Съхранена процедура:
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'
Екранните снимки няма да покрият SP, насочен към една база данни, защото изходът е същият, единствената разлика е, че показва една база данни.
Както можете да видите, данните за колоните „Differential“ са NULL, защото никога не съм правил диференциално архивиране за нито една от тях. Въпреки това, за да демонстрираме напълно колко полезно може да бъде това решение, се нуждаем от диференциално резервно копие. Ще взема един за базата данни на DBA и ще изпълня съхранената процедура, за да видя какво връща:
EXEC DBA_DatabaseBackups @database = 'DBA', @backupType = 'D'
След като направите диференциалното архивиране, можете да видите, че нашата съхранена процедура връща данните и за колоните на диференциала, точно на резервното копие, което току-що направих.
Пълният код на съхранената процедура
В самото начало на скрипта ще видите стойности по подразбиране – скриптът ги приема, ако не се подаде стойност за всеки параметър.
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
Заключение
С тази персонализирана съхранена процедура можете да изградите механизъм, който да ви предупреждава, когато определен тип архивиране за дадена база данни не е направен в рамките на определен период.
Можете да разположите тази съхранена процедура във всеки екземпляр на SQL Server и да проверите информацията за архивиране за всяка отделна база данни (системни и потребителски бази данни).
Освен това можете да използвате информацията, върната от съхранената процедура, за да създадете карта на резервни копия за да идентифицирате местоположението на последния архивен файл за всяка база данни. В настоящата си работа използвах това, за да създам скрипт, който да организира тестовете за възстановяване на всички резервни копия под моята поддръжка и да потвърдя, че са 100% надеждни. За мен това беше изключително полезно.