Восстановление базы 1С SQL-Server
Эта статья о том, как не допустить потерю данных, а в случае, если это всё таки произошло, как восстановить данные из того, что осталось от некогда нормальной базы.
Итак, начнем. Рассмотрим следующую ситуацию: есть сервер с запущенной и работающей на нем связкой 1С+SQL.
Во время работы SQL вдруг выключилось питание сервера. Результат плачевный: база находится в состоянии suspect, и когда 1с пытается к ней зацепиться, выдается ошибка, что мол соединиться невозможно т.к. база помечена suspect for recovery.
Этот режим в принципе означает, что MSSQL Server попытается восстановить базу своими средствами. Я не стал ни чего трогать и оставил все на ночь, в надежде, что к утру база восстановится, но и утром было то же самое, и к базе, стало быть, ни как не подобраться.
Backup по закону подлости имеется, но он трехдневной давности, плюс имеется куча документов которые проводятся лишь по базе, а по бумажным документам их нет, т.е. возможности вручную восстановить документы нет. Потратив кучу сил, и нервов, (которые, как известно не восстанавливаются :)), я пришел к следующей последовательности действий, необходимых для восстановления базы.
1) Главный принцип при этих манипуляциях – не навредить. Останавливаем SQL server и делаем копии файлов *.mdf и *.ldf файлы от базы в отдельную папку.
2) В принципе, бывает, что состояние suspect возникает из-за того, что поменялись пути к файлам с базой (например, добавился новый диск в системе, который потом убрали, переименовали папку с базой и т.д.). Затем, конечно же, пути восстановили, но база все равно остается помеченной как suspect.
Что надо сделать:
3) Запустить SQL Server.
4) Попробывать подключить базу посредством Enterprise Manager:
Правой кнопкой по Databases, в появившемся меню выбираем All tasks->Attach database, затем в появившемся диалогов окне выбираем файл с базой (*.mdf) и устанавливаем необходимые параметры.
5) или через Query Analyser примерно такой командой:
a. sp_attach_db @dbname = 'DemoXMB',
b. @filename1 = 'E:\Data\DemoXMB_Data.MDF',
c. @filename2 = 'E:\Data\DemoXMB_Log.LDF'
6) Пути к базе, естественно нужно заменить на свои. Если база подключилась, то, можно сказать, отделались легким испугом, если же нет, то продолжим.
7) Если log-файл не поврежден (*.ldf), а поврежден *.mdf (например, при подключении базы sql ругается на ошибки в mdf-файле), и режим сохранения backup'а стоит full, то восстанавливаем базу без восстановления лога транзакций, почти 100%, что все мучения на этом могут закончиться.
8) Если же наоборот, поврежден ldf-файл, но остался *.mdf файл, при подключении база ругается на отсутствие/повреждение лога транзакций. В этом случае можно воспользоваться ХП "sp_attach_single_file_db"
Например:
use master
EXEC sp_attach_single_file_db @dbname = 'DemoXMB',
@physname = 'c:\mssql7\data\DemoXMB_Dat.mdf'
При выполнении этих команд, создастся файл DemoXMB_Log.ldf в том же каталоге где и база, размером 1MB и авторасширением.
Если есть *.MDF и *.LDF-файлы, или данные хранятся более чем в одном физическом файле (общее количество подключаемых физических файлов не должно превышать 16-ти), то следует использовать ХП "sp_attach_db"
Например:
use master
EXEC sp_attach_db @dbname = 'DemoXMB',
@filename1 = 'c:\mssql7\data\DemoXMB_Dat.mdf',
@filename1 = 'c:\mssql7\data\DemoXMB_Log.ldf'
Для подключения более 16-ти физических файлов к БД следует использовать команду:
CREATE DATABASE FOR ATTACH
Однако если ничего не помогло, оказались поврежденными оба файла и база всё еще в состоянии suspect, то можно попробовать сбросить состояние базы следующей последовательностью: (перед использованием этой ХП необходимо разрешить прямое изменение системных таблиц:
use master
go
Разрешаем прямое изменение системных таблиц:
sp_configure 'allow updates',1
go
reconfigure with override
go
Для сброса признака suspect выполняем в БД master ХП sp_resetstatus:
sp_resetstatus 'DataBaseName'
go
А теперь запретим прямое изменение системных таблиц:
sp_configure 'allow updates',0
go
reconfigure with override
go
В принципе, когда я выполнил все эти шаги, статус suspect сбросился, НО! при попытке выполнить какие-либо действия SQL начинала ругаться, что база все еще в состоянии suspect. И тогда я сделал так:
Из QA выполняем скрипт:
Use master
go
sp_configure 'allow updates', 1
reconfigure with override
go
Там же выполняем:
update sysdatabases set status= 32768 where name = '<db_name>'
Перезапускаем SQL Server. В принципе база должна быть видна (в emergency mode).
Из QA выполняем:
USE '<db_name>'
GO
sp_dboption '<db_name>', 'single_user', 'true'
go
DBCC CHECKDB('<db_name>', REPAIR_ALLOW_DATA_LOSS)
go
Если все в порядке, то:
sp_dboption '<db_name>', 'single_user', 'false'
go
Use master
go
sp_configure 'allow updates', 0
go
После этого стало возможно просмотреть таблицы базы из SQL, а вот работать с ней было невозможно. Теперь необходимо при помощи Data Transformation Services экспортировать данные в новую базу. После этого проводим восстановление/тестирование базы средствами 1С. Внимание! Многие не обращают внимания на этот очень важный пункт. В результате, вы можете в один прекрасный момент обнаружить, что база восстановлена, мягко говоря, не совсем корректно. Т.е. в документе вместо номенклатуры будет стоять нечто вроде 10122/<Объект не найден>, это та проблема, которая возникла у меня, вариантов же может быть уйма. Поэтому лучше потерять время, но проверить базу средствами 1С.
Если уж совсем ничего не помогает, а данные страсть как нужно восстановить, есть еще сторонняя утилита под названием MSSQLRecovery . Утилита платная, но есть возможность воспользоваться демонстрационной версией, которую можно взять здесь: http://www.officerecovery.com/mssql/download_demo.htm . Программа очень простая, и восстановление базы сводится к трем шагам: 1) выбираем файл с базой; 2) выбираем путь куда сохранять; 3) Жмем кнопку recovery; Ждем. Программа разбирает SQL-базу по косточкам и складывает ее в отдельный каталог. Туда же она добавляет и .bat файл для восстановления базы из полученных «кусочков». Я ей так и не воспользовался, т.к. сумел восстановить базу предыдущими шагами.
Но! Здесь следует сделать паузу. Статья не была бы полной, если бы я не описал методы для предотвращения подобных проблем. Итак, самый простой и надежный способ: архивация, архивация и еще раз архивация. В Enterprise Manager заходим в меню Tools->Wizards->Management->Backup Wizard и настраиваем все необходимые параметры. В результате, у меня полный сброс SQL базы на диск происходит ночью, а затем каждые 15 минут backup изменений, внесенных в базу. В принципе, если бы у меня был такой backup, я бы за пару минут сделал откат назад, и продолжил бы попивать Coca-Cola :).