Бывает, что одна секунда изменяет реальность вокруг вас... Особенно эта реальность изменяется, когда вы осознаете, что "теряете" важные данные вместе с БД, а резервной копии, как назло, нет. Или нет "под руками". Думаю, кто-то увидит себя в подобной ситуации. Да и в моей практике такое тоже случалось. Причины могут быть крайне разнообразны: от технических до патологических :)
В таких случаях возможны два грустных сценария:
Перейдем к делу. В данной заметке рассматривается подход на примере MS SQL Server 2005. Очень частая проблема - это когда у вас по каким-либо причинам есть файл БД *.mdf, но нет файла-лога SQL Server *.ldf. При попытке получить доступ к такой БД SQL Server выдаст ошибку: Database 'DBName' cannot be opened due to inaccessible files or insufficient memory or disk space. Симптомы, кстати, могут быть разными. БД будет отображаться в списке в Management Studio, но доступ к ней не будет возможным. Создание пустого файла .ldf тоже не помогает в таких случаях.
Дальнейшие действия относятся к SQL Server 2005.
1. Сохраняем резервную копию имеющегося файла БД (*.mdf) и работаем только с копией.
2. Удаляем из списка элемент, который указывал на нашу БД.
3. Создаем новую пустую БД с таким же названием. SQL Server автоматически создаст файл лога.
4. Останавливаем сервис SQL Server, чтобы освободить дескрипторы файлов БД.
5. Копируем поверх вновь созданного SQL-сервером .mdf-файла наш имеющийся файл с данными, подлежащими восстановлению.
6. Запускаем сервис SQL Server. Мы по-прежнему видим в списке нашу БД. И по-прежнему не можем получить в ней доступ. Сервер "видит", что файл лога не соответствует нашему .mdf, что и логично.
7. Далее необходимо выполнить ряд команд над БД.
- перевести БД в Emergency Mode:
ALTER DATABASE targetdatabase SET EMERGENCY
- установить опцию монопольного доступа к базе данных:
exec sp_dboption targetdatabase, 'single user', 'TRUE'
- запустить процесс проверки логической и физической целостности БД с, в данном случае, опцией REPAIR_ALLOW_DATA_LOSS. Да, возможны потери данных, но на практике часто восстанавливаются и они. Особенно стоит обратить внимание при создании БД на опцию Recovery Model (Simple, Full, ...). Скажем, для примера (можете потестировать с копией), на БД размером в десяток-другой гигабайт с моделью Simple при "просто потере файла логов и некорректном завершении работы с базой" данные, как правило, восстанавливаются тоже. Зависит, конечно, от сложности структуры в том числе.
DBCC CHECKDB (targetdatabase, REPAIR_ALLOW_DATA_LOSS)
Проверка (в зависимости от объема данных) может занять довольно продолжительное время. Впрочем, несколько минут - это недолго, по сравнению с возможными последствиями. Очень вероятно, что на данном этапе вы получите весьма многострочный лог ошибок. Однако, движемся далее...
- сбрасываем опцию монопольного доступа:
exec sp_dboption targetdatabase, 'single user', 'FALSE'
- возвращаем БД к жизни:
ALTER DATABASE targetdatabase SET ONLINE
Вполне вероятно, что на данном этапе вы получите версию БД в том виде, за который вам ничего плохого не сделают :)
Да, также можно попытаться подключить БД и без лога напрямую, выполнив следующую 'last chance' команду:
exec sp_attach_single_file_db 'targetdatabase', 'path\to\TargetDatabase.mdf'
Правда, первый вариант сработает, судя по всему, в большем количестве случаев. Как видим - команд не так уж и много, но "держать на уме", что называется, на подхвате, никогда не помешает. Не забываем о резервных копиях! Однако, замечу, описанный вариант может позволить восстановить базу в том состоянии, в котором ее и "потеряли".
Данный пост касается SQL Server 2005. В других версиях действия не проверялись.
- потеря данных, но сохранение структуры БД и сопутствующих структур (функции, триггеры, хранимые процедуры и тд);
- потеря и данных, и их структуры (совсем уж грустный случай).
Релоцировались? Теперь вы можете комментировать без верификации аккаунта.