Скрипт для проверки на наличие всех бэкапов с момента последнего full backup.
Зачем оно нужно: если отсутствует файл последнего full backup (или любой из последующих лог-файлов) – разорвана цепочка архивирования и её неплохо бы начать заново.
Для работы требуется:
- вы не вызывали очищали историю бэкапов (например, при помощи sp_delete_backuphistory) с момента последнего full backup.
- Способ проверки файла на существование. В SQL Server есть недокументированная xp_fileexist, но мне было лень возиться с курсорами, и я использовал самописную CLR Function.
public static class FileSystemHelper
{
[SqlFunction(
DataAccess = DataAccessKind.None, IsDeterministic = false, IsPrecise = true,
SystemDataAccess = SystemDataAccessKind.None)]
public static bool FileExists(string path)
{
return File.Exists(path);
}
}
Код:
-- CREATE VIEW [Maintenance].[MaintainedDatabases]
-- AS
WITH LastFullBackupSets
AS
(
SELECT BS.database_guid, BS.database_name, MAX(BS.last_lsn) AS last_lsn
FROM msdb.dbo.backupset BS
INNER JOIN msdb.dbo.backupmediafamily BMF
ON BS.media_set_id=BMF.media_set_id
WHERE BS.type=N'D'
AND BMF.device_type = 2
GROUP BY BS.database_guid, BS.database_name
),
BackupFiles
AS
(
SELECT BS.database_guid, BS.database_name, BMF.physical_device_name
FROM msdb.dbo.backupset BS
INNER JOIN msdb.dbo.backupmediafamily BMF
ON BS.media_set_id=BMF.media_set_id
INNER JOIN LastFullBackupSets LBS
ON BS.database_name = LBS.database_name
AND BS.database_guid = LBS.database_guid
WHERE BMF.device_type = 2
AND BS.last_lsn >= LBS.last_lsn
GROUP BY BS.database_guid, BS.database_name, BMF.physical_device_name
),
DBBackupStatus
AS
(
SELECT BF.database_name, BF.database_guid,
-- !!! Replace to your own func.
MIN(CAST(FileSystem.FileExists(BF.physical_device_name) AS int)) AS all_backups_exists
FROM BackupFiles BF
GROUP BY BF.database_guid, BF.database_name
)
SELECT D.database_id AS ID, D.name AS Name,
CAST (ISNULL(DBBS.all_backups_exists, 0) AS bit) AS HasValidBackupChain,
CAST (CASE WHEN D.recovery_model_desc = N'SIMPLE' THEN 0 ELSE 1 END AS bit) AS UsesLogBasedRecovery
FROM sys.databases D
INNER JOIN sys.database_recovery_status DRS ON D.database_id = DRS.database_id
LEFT JOIN DBBackupStatus DBBS
ON D.name = DBBS.database_name
AND DRS.database_guid = DBBS.database_guid
WHERE D.name <> N'tempdb';
UPD: Извиняюсь за кошмарное форматирование кода. Бум думать
Комментариев нет:
Отправить комментарий