“Универсальный” скрипт для восстановления бэкапа на SQL Server
Ну, сделали мы бэкап!? Ну, валяется он у нас на диске... А дальше что?! Как проверить является ли этот “файлик” корректным (валидным)?! Где гарантии, что когда припечет, этот “файлик” сотворит чудо и восстановит базу до момента сбоя?!
К сожалению таких гарантий никто не даст. Поэтому, нужно максимально проверить является ли этот “файлик” корректным, восстановится ли он в нужным момент. В данной статье я постараюсь максимально повысить вероятность того, что файл бэкапа (который мы все, надеюсь, делаем) восстановится без проблем.
Начнем с того, что у каждого администратора баз данных должно быть две основные схемы: схема бэкапирования и схема восстановления базы.
Схема бэкапирования – админ сам решает, когда ему делать полный бэкап базы, когда ему делать разностный бэкап и не забывает о бэкапе лога транзакций.
Схема восстановления – проверка правильности бекапа, и в случае сбоя базы восстановить все то, что годами набирали наши любимые бухгалтера одним нажатием пальца.
Если использовать команды языка sql то проверку валидности сделанного бэкапа можно проверить так:
--Проверка валидности бэкапа
RESTORE VERIFYONLY FROM DISK = N'указываеться полный путь к бэкапу'
--А если БД бэкапилась на бэкап устройсто (Backup Device)
RESTORE VERIFYONLY FROM [Device Name]
Есть одно «но». Эта проверка не позволяет с уверенность сказать, что бэкап восстановится. Единственным и правильным способом проверить является ли наш “файлик” валидным – это пробовать трансформировать наш бэкап с помощью команды RESTORE в базу данных. И если востановление “файлика” прошло успешно, можно говорить что наш бэкап корректный.
Эсть сервер MsSQL1 который бэкапит базы локально, а потом копирует базы на сетевой диск '\\XXX.XXX.XXX.XXX\SWBackUp' и есть второй сервер MsSQL2, который связан с MsSQL1. Выполняем скрипт на сервере MsSQL2 и восстанавливаем нужную нам базу из бэкапа! Это все нужно для того, чтобы главный сервер MsSQL1 был "практически не задействован" в этом процессе
DECLARE @NameDB NVARCHAR(100)
DECLARE @NameBackUp NVARCHAR(100)
DECLARE @SQL NVARCHAR(300)
SELECT @NameDB=bs.[database_name],
@NameBackUp=substring(bmf.[physical_device_name],len(rtrim(bmf.[physical_device_name])) - patindex('%\%',reverse(rtrim(bmf.[physical_device_name])))+2,len(bmf.[physical_device_name]))
FROM [MsSQL1].[msdb].[dbo].[backupset] bs, [MsSQL1].[msdb].[dbo].[backupmediafamily] bmf
WHERE bs.[media_set_id]=bmf.[media_set_id] AND bs.[backup_finish_date] IN
(SELECT max ([backup_finish_date]) FROM [MsSQL1].[msdb].[dbo].[backupset] WHERE [type]='D' and [database_name]='portal2')
SET @SQL='RESTORE DATABASE '+@NameDB+ ' FROM DISK=''\\XXX.XXX.XXX.XXX\SWBackUp\'+@NameDB+'\'+@NameBackUp+ ''' WITH NORECOVERY'
--print @SQL
execute sp_executesql @SQL
А потом накатываем последнюю дифференциальную резервную копию этой же базы
DECLARE @NameDB NVARCHAR(100)
DECLARE @NameBackUp NVARCHAR(100)
DECLARE @SQL NVARCHAR(300)
SELECT @NameDB=bs.[database_name],
@NameBackUp=substring(bmf.[physical_device_name],len(rtrim(bmf.[physical_device_name])) - patindex('%\%',reverse(rtrim(bmf.[physical_device_name])))+2,len(bmf.[physical_device_name]))
FROM [MsSQL1].[msdb].[dbo].[backupset] bs, [MsSQL1].[msdb].[dbo].[backupmediafamily] bmf
WHERE bs.[media_set_id]=bmf.[media_set_id] AND bs.[backup_finish_date] IN
(SELECT max ([backup_finish_date]) FROM [MsSQL1].[msdb].[dbo].[backupset] WHERE [type]='I' and [database_name]='portal2')
SET @SQL='RESTORE DATABASE '+@NameDB+ ' FROM DISK=''\\XXX.XXX.XXX.XXX\SWBackUp\'+@NameDB+'\'+@NameBackUp+ ''' WITH RECOVERY'
--print @SQL
execute sp_executesql @SQL
А далее записываем скрипты в джоб и выполняем в нужное для нас время.