Бывает, что одна секунда изменяет реальность вокруг вас... Особенно эта реальность изменяется, когда вы осознаете, что "теряете" важные данные вместе с БД, а резервной копии, как назло, нет. Или нет "под руками". Думаю, кто-то увидит себя в подобной ситуации. Да и в моей практике такое тоже случалось. Причины могут быть крайне разнообразны: от технических до патологических :)
В таких случаях возможны два грустных сценария:
потеря данных, но сохранение структуры БД и сопутствующих структур (функции, триггеры, хранимые процедуры и тд);
потеря и данных, и их структуры (совсем уж грустный случай).
Ведь довольно часто встречаются проекты, где бизнес-логика реализована на уровне БД, выдавая только интерфейс для работы с данными к 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\'
Правда, первый вариант сработает, судя по всему, в большем количестве случаев. Как видим - команд не так уж и много, но "держать на уме", что называется, на подхвате, никогда не помешает. Не забываем о резервных копиях! Однако, замечу, описанный вариант может позволить восстановить базу в том состоянии, в котором ее и "потеряли".
Из практики, была база которая упала неподьемно!!!
ALTER DATABASE <Имя БД> SET SINGLE_USER (монопольный юзер)
DBCC CHECKDB (<Имя БД>, REPAIR_ALLOW_DATA_LOSS) (устранение ошибок)
DBCC CHECKDB (<Имя БД>, REPAIR_REBUILD) (еще это не помешает по устранению ошибок)
ALTER DATABASE <Имя БД> SET ONLINE (приводим к работоспособности)
ALTER DATABASE <Имя БД> SET MULTI_USER (многопользовательскй доступ)
И еще неплохая статейка расширено тут посмотреть.
В таких случаях возможны два грустных сценария:
потеря данных, но сохранение структуры БД и сопутствующих структур (функции, триггеры, хранимые процедуры и тд);
потеря и данных, и их структуры (совсем уж грустный случай).
Ведь довольно часто встречаются проекты, где бизнес-логика реализована на уровне БД, выдавая только интерфейс для работы с данными к 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 (многопользовательскй доступ)
И еще неплохая статейка расширено тут посмотреть.
Комментариев нет:
Отправить комментарий