воскресенье, 19 апреля 2015 г.

Восстановление БД в MS SQL Server 2005 и выше (к сожалению не всегда помагает)

Бывает, что одна секунда изменяет реальность вокруг вас... Особенно эта реальность изменяется, когда вы осознаете, что "теряете" важные данные вместе с БД, а резервной копии, как назло, нет. Или нет "под руками". Думаю, кто-то увидит себя в подобной ситуации. Да и в моей практике такое тоже случалось. Причины могут быть крайне разнообразны: от технических до патологических :) 

В таких случаях возможны два грустных сценария: 
потеря данных, но сохранение структуры БД и сопутствующих структур (функции, триггеры, хранимые процедуры и тд); 
потеря и данных, и их структуры (совсем уж грустный случай). 

Ведь довольно часто встречаются проекты, где бизнес-логика реализована на уровне БД, выдавая только интерфейс для работы с данными к application. Так вот, последствия могут быть очень грустными, если действительно нет резервной копии. Причем, бывает, что потеря структуры БД - не менее важная потеря, чем самих данных (особенно тестовых). Ведь на структуру тоже затрачивалось время. 

Перейдем к делу. В данной заметке рассматривается подход на примере 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\' 

Правда, первый вариант сработает, судя по всему, в большем количестве случаев. Как видим - команд не так уж и много, но "держать на уме", что называется, на подхвате, никогда не помешает. Не забываем о резервных копиях! Однако, замечу, описанный вариант может позволить восстановить базу в том состоянии, в котором ее и "потеряли". 

Из практики, была база которая упала неподьемно!!!


T-SQL команды запускаем пошагово одна за другой: 

ALTER DATABASE <Имя БД> SET EMERGENCY  (перевод базы в режим "лечение")
ALTER DATABASE <Имя БД> SET SINGLE_USER  (монопольный юзер)
DBCC CHECKDB (<Имя БД>, REPAIR_ALLOW_DATA_LOSS)  (устранение ошибок)

DBCC CHECKDB (<Имя БД>, REPAIR_REBUILD) (еще это не помешает по устранению ошибок)
ALTER DATABASE <Имя БД> SET ONLINE (приводим к работоспособности)

ALTER DATABASE <Имя БД> SET MULTI_USER  (многопользовательскй доступ)


И еще неплохая статейка расширено тут посмотреть.



Комментариев нет:

Отправить комментарий