При работе с SQL Server администраторы часто сталкиваются с ситуацией, когда попытка развернуть тестовую базу из бэкапа приводит к неожиданным последствиям для основной рабочей базы. В частности, рабочая база может внезапно перейти в состояние «Восстановление...» (Restoring) и стать недоступной для пользователей. Рассмотрим подробно, почему это происходит, как спасти данные и как не допустить подобного в будущем.
Проанализируем механику работы мастера восстановления в SQL Server Management Studio (SSMS). Когда мы инициируем процесс Restore Database, система по умолчанию пытается защитить целостность данных. Главным «виновником» того, что рабочая база уходит в офлайн, является опция «Take tail-log backup before restore» (Сделать бэкап хвоста лога перед восстановлением).
Разберем по шагам, что делает SQL Server при включении этой опции:
BACKUP LOG ... WITH NORECOVERY.NORECOVERY переводит базу в состояние ожидания последующих логов. В этом режиме база считается неконсистентной (так как ожидаются новые данные) и закрывается для любых подключений.Даже если в процессе настройки вы изменили имя целевой базы на «Test» и указали новые пути к файлам .mdf и .ldf, флаг создания бэкапа хвоста лога может остаться привязанным к контексту исходной (рабочей) базы, из меню которой был вызван мастер. В итоге: тестовая база успешно восстановилась, а рабочая осталась «ждать» логов, которые вы не планировали накатывать.
Прежде чем выполнять любые команды по восстановлению, проанализируем состояние файлов. Если база находится в состоянии «Restoring», это не означает, что данные удалены. Это лишь статус в системном каталоге master. Однако, чтобы исключить риск человеческой ошибки, выполним следующие действия:
C:\Program Files\Microsoft SQL Server\...\MSSQL\DATA).ИмяБазы.mdf и ИмяБазы_log.ldf в безопасное место.Теперь, имея физическую копию файлов, мы можем приступать к программному выводу базы из «заморозки».
Рассмотрим основной способ решения проблемы. Нам необходимо подать сигнал SQL-серверу, что никаких дополнительных транзакций из логов восстанавливать не нужно, и базу можно переводить в оперативный режим (Online). Для этого используется команда RESTORE с параметром RECOVERY.
Откроем New Query в SSMS и выполним следующий скрипт:
USE [master];
GO
RESTORE DATABASE [Имя_Вашей_Рабочей_Базы] WITH RECOVERY;
GO
Проанализируем результат выполнения. Если в окне сообщений вы увидите текст: RESTORE DATABASE успешно обработал 0 страниц, это хороший знак. Это означает, что SQL Server просто изменил флаг состояния базы в системных таблицах, не затрагивая сами данные. База должна мгновенно стать доступной.
Чтобы в будущем процедура создания тестовых баз проходила безболезненно, разберем правильный алгоритм работы с интерфейсом SSMS:
.mdf и .ldf должны вести к новым файлам тестовой базы, а не затирать рабочие.Посмотрим на пример правильного скрипта для восстановления в другую базу, который гарантированно не затронет рабочую:
RESTORE DATABASE [Test_Base]
FROM DISK = N'D:\Backups\Work_Base.bak'
WITH FILE = 1,
MOVE N'Work_Base_Data' TO N'D:\SQL_Data\Test_Base.mdf',
MOVE N'Work_Base_Log' TO N'D:\SQL_Data\Test_Base_log.ldf',
NOUNLOAD,
STATS = 5;
Обратите внимание, что в данном скрипте отсутствует команда BACKUP LOG и параметры NORECOVERY, что делает процедуру безопасной для исходной базы данных.
Иногда база может перейти в состояние «Standby / Read-Only». Это происходит, если при восстановлении была выбрана опция сохранения файла отката (undo file). В этом случае база доступна для чтения, но в ней нельзя изменять данные. Вывод из этого состояния осуществляется точно так же — командой WITH RECOVERY, которая завершает процесс восстановления и делает базу полнофункциональной.
Подводя итог, отметим: состояние «Restoring» для рабочей базы при манипуляциях с тестовой — это следствие избыточной «заботы» графического интерфейса SSMS о сохранности ваших логов. Использование ручного выполнения RESTORE ... WITH RECOVERY является стандартным и безопасным методом возвращения базы в строй при условии, что вы не планировали продолжать восстановление из цепочки бэкапов лога транзакций.