Восстановление БД MS SQL из статуса Suspect

    Рассмотрим несколько вариантов восстановления БД, в зависимости от того, насколько повреждены файлы БД зависит успешность того или иного метода. Все описанные способы были лично мной проверены на практике и все случаи восстановления, за исключением одного, были успешны. Используйте данное руководство на свой страх и риск, за совершенные вами действия ответственность несете, вы сами.

    Итак, во-первых останавливаем службу SQL Server и копируем файлы базы данных (*.mdf и *.ldf) в другую папку, чтобы можно было восстановить их в случае неудачи.

    Если у вас есть свежий актуальный бэкап, то дальше можете не читать, а просто восстановите БД из него, тем самым сэкономите драгоценное время, далее я приведу алгоритмы восстановления для разных версий SQL Server. Надеюсь вам это поможет, как в свое время помогло и мне.

    Для всех версий SQL Server подойдет следующий вариант: делаем Detach database (отсоединить базу данных), удаляем журнал транзакций (файл с расширением ldf) и делаем Attach database(присоединить базу данных). В мастере выбираем наш mdf файл и жмем ОК.

    Если mdf файл не поврежден, то он успешно присоединится и мы увидим нашу базу в диспетчере объектов целую и невредимую.

    Радуемся успешному восстановлению. (Этот вариант сработает только если mdf файл не поврежден, поэтому срабатывает не всегда). Если не получилось, то создаем новую базу данных с таким же именем, останавливаем сервер. Подменяем файл mdf файлом от нашей базы, стартуем службу SQL Server и открываем Query analyzer(SQL 2000) или Management studio(SQL 2005/2008) в зависимости от нашей версии сервера.

    Пишем следующее:

    USE master
    GO
    sp_configure 'allow updates', 1
    reconfigure WITH override
    GO

    Если у вас SQL 2000, то далее пишем:

    UPDATE sysdatabases SET STATUS= 32768 WHERE name = 'db_name'
    GO

    Если SQL 2005 или 2008, то пишем:

    ALTER DATABASE db_name SET EMERGENCY, SINGLE_USER
    GO

    где вместо db_name пишем имя своей БД

    Жмем F5. После этого наша БД должна быть видна в статусе EMERGENCY.

    В особо тяжелых случаях возникают проблемы с переходом в EMERGENCY, возможны даже проблемы с detach, в таких случаях поврежденная база удаляется, а далее происходит хитрая подмена файлов данных. Для начала создадим новую базу, имена файлов mdf и ldf должны совпадать с именами файлов поврежденной базы. Новую базу переводим в режим EMERGENCY, останавливаем службу MSSQL и подменяем файлы поврежденными. Таким образом мы получим рабочий инстанс в статусе EMERGENCY с поврежденными файлами.

    Отлично, приступаем к восстановлению.

    Выполним следующие SQL команды.

    Для SQL 2000:

    DBCC REBUILD_LOG('db_name', 'Полный путь к новому файлу ldf')
    GO

    Жмем F5, если все нормально, сервер скажет: Warning: The log for database ‘db_name’ has been rebuilt.

    Стираем и пишем:

    USE master
    GO
    sp_dboption 'db_name', 'single user', 'true'
    GO
    USE db_name
    GO
    DBCC CHECKDB('db_name', REPAIR_REBUILD)
    GO

    Если база не хочет в single mode можно попробовать такую команду

    USE db_name
    ALTER database db_name set SINGLE_USER with rollback immediate
    GO

    если DBCC не хочет выполняться, то вместо REPAIR_REBUILD нужно подставить REPAIR_ALLOW_DATA_LOSS

    Жмем F5, ждем некоторое время. Сервер вернет кучу сообщений. Если там будут содержаться ошибки, то лучше еще раз выполнить DBCC CHECKDB с параметром REPAIR_REBUILD, пока все ошибки не будут устранены.

    Для SQL 2005/2008 действия несколько иные:

    DBCC CHECKDB('db_name', REPAIR_ALLOW_DATA_LOSS)
    GO

    Тут без вариантов. В SQL 2005 и выше нет инструкции REBUILD_LOG, вместо этого выполняется CHECKDB с параметром REPAIR_ALLOW_DATA_LOSS.

    После того как сервер закончит выполнять запрос и вернет результат, меняем REPAIR_ALLOW_DATA_LOSS на REPAIR_REBUILD и выполняем запрос еще раз, это должно убрать оставшиеся ошибки в бд.

    После всего этого наша база становится в нормальное состояние и уже доступна для работы с ней, но только в однопользовательском режиме, поэтому завершаем наш процесс возвращением бд в многопользовательский режим.

    Пишем:

    Для SQL 2000:

    USE master
    GO
    sp_dboption 'db_name', 'single user', 'false'
    GO

    Для SQL 2005/2008:

    ALTER DATABASE db_name SET ONLINE, MULTI_USER
    GO

    Все. База онлайн и готова к работе. Радуемся и не забываем делать бэкапы.

    Tags: ,