Восстановление базы данных MS SQL Server — это возврат БД в согласованное рабочее состояние после сбоя: либо накатом резервной копии (RESTORE), либо ремонтом поврежденных страниц средствами DBCC CHECKDB (repair). Это два разных пути, и путать их нельзя: RESTORE возвращает данные без потерь до точки бэкапа, а repair в тяжелом режиме удаляет то, что не смог починить. Ниже — как отличить состояния БД, поставить диагноз через DBCC CHECKDB и выбрать безопасный путь; проверено на SQL Server 2019/2022, синтаксис актуален и для более ранних версий начиная с 2012.
Содержание
- Сначала — диагностика: в каком состоянии база
- DBCC CHECKDB: проверка целостности (безопасно)
- Уровни repair: чем отличаются
- RESTORE из бэкапа против repair: что выбирать
- EMERGENCY mode: последняя мера для SUSPECT без бэкапа
- Сторонние утилиты: когда штатных средств мало
- Выводы
- Где применяется / связь с практикой
- FAQ
Три термина, которые постоянно смешивают, разведем сразу:
- recovery (восстановление согласованности) — фаза, которую движок сам проходит при старте БД: накат (redo) подтвержденных и откат (undo) незавершенных транзакций по журналу. Это не про резервные копии.
- RESTORE (восстановление из резервной копии) — команда, которая перезаписывает БД содержимым файлов
.bak/.trn. Основной и предпочтительный способ вернуть данные. - repair (ремонт) — опции
DBCC CHECKDB (..., REPAIR_...), которые правят физические повреждения страниц. Крайняя мера, когда бэкапа нет.
Сначала — диагностика: в каком состоянии база
Не начинайте с ремонта. Сначала посмотрите состояние всех БД и модель восстановления — от этого зависит, доступен ли вам бэкап журнала.
SELECT name, state_desc, recovery_model_desc
FROM sys.databases
ORDER BY name;
-- state_desc: ONLINE, RESTORING, RECOVERY_PENDING, SUSPECT, EMERGENCY, OFFLINE
Что означают проблемные состояния и с чего начинать — в таблице. Важно: SUSPECT и RECOVERY_PENDING — разные диагнозы, и лечатся по-разному.
| Состояние | Вероятная причина | Первое действие (не repair) |
|---|---|---|
| RECOVERY_PENDING | Движок не смог даже начать recovery: нет файла журнала, нет места на диске, нет прав к файлу | Устранить ресурсную причину (вернуть файл, освободить диск), затем ALTER DATABASE ... SET ONLINE |
| SUSPECT | recovery началась, но не завершилась: поврежден или отсутствует журнал, сбой ввода-вывода | Восстановить из резервной копии; если бэкапа нет — EMERGENCY + DBCC CHECKDB |
| RESTORING | Цепочка RESTORE оставлена в состоянии NORECOVERY (это норма посреди восстановления) | Догнать последним RESTORE ... WITH RECOVERY |
RECOVERY_PENDING часто чинится без всякого ремонта данных — вернули потерянный файл журнала или освободили место, и база поднялась. Это упрощенная модель: в редких случаях за RECOVERY_PENDING стоит и физическое повреждение, тогда переходят к диагностике ниже.
DBCC CHECKDB: проверка целостности (безопасно)
DBCC CHECKDB без опций ремонта только читает и сообщает об ошибках — состояние БД он не меняет, запускать можно на рабочей базе (с учетом нагрузки).
DBCC CHECKDB (N'Sales') WITH NO_INFOMSGS, ALL_ERRORMSGS;
-- NO_INFOMSGS убирает информационный шум, ALL_ERRORMSGS показывает все найденные ошибки
В конце вывода CHECKDB печатает рекомендованный минимальный уровень ремонта, например: repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB. Эта строка — подсказка, а не приказ немедленно запускать разрушающий ремонт: сначала оцените, есть ли резервная копия.
Уровни repair: чем отличаются
У ремонта два рабочих уровня. Оба требуют перевода БД в однопользовательский режим — иначе команда завершится ошибкой.
| Уровень | Что делает | Потеря данных |
|---|---|---|
| REPAIR_REBUILD | Чинит легкие повреждения: перестраивает некластерные индексы, правит ошибки, не затрагивающие данные | Нет |
| REPAIR_ALLOW_DATA_LOSS | Освобождает поврежденные страницы и пересобирает связи; исправляет тяжелые ошибки | Да — удаленные страницы теряются вместе с данными |
Устаревший REPAIR_FAST синтаксис принимает, но никаких действий он не выполняет — оставлен только для обратной совместимости, использовать его нет смысла.
REPAIR_REBUILD безопасен по данным, с него и начинают, если CHECKDB указал именно его:
-- Безопасный ремонт: без потери данных, но нужен монопольный доступ
ALTER DATABASE Sales SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DBCC CHECKDB (N'Sales', REPAIR_REBUILD) WITH NO_INFOMSGS, ALL_ERRORMSGS;
ALTER DATABASE Sales SET MULTI_USER;
WITH ROLLBACK IMMEDIATE откатывает чужие активные транзакции, чтобы получить монопольный доступ — это тоже изменение состояния, предупредите пользователей заранее.
RESTORE из бэкапа против repair: что выбирать
Правило простое: если есть годная резервная копия — восстанавливайте из нее, а не ремонтируйте. RESTORE возвращает данные без потерь до точки бэкапа; REPAIR_ALLOW_DATA_LOSS почти всегда что-то теряет. Ремонт с потерей данных — крайняя мера, когда бэкапа нет или он тоже поврежден.
Перед любым восстановлением при полной (FULL) или bulk-logged модели снимите резервную копию хвоста журнала (tail-log backup) — это последние записи, которых еще нет ни в одном бэкапе. Пропустите этот шаг — потеряете все транзакции с момента последней копии журнала.
-- Хвост журнала: последние незабэкапленные транзакции
BACKUP LOG Sales
TO DISK = N'D:\Backup\Sales_tail.trn'
WITH NORECOVERY;
-- Если файл ДАННЫХ поврежден, но сам журнал цел и обычный бэкап не проходит,
-- добавить NO_TRUNCATE (снимает хвост даже при недоступной БД):
-- WITH NORECOVERY, NO_TRUNCATE;
-- Если поврежден уже журнал и NO_TRUNCATE не проходит,
-- пробуют CONTINUE_AFTER_ERROR ВМЕСТО NO_TRUNCATE (бэкап уже ненадежен).
WITH NORECOVERY оставляет БД в состоянии восстановления, готовой принять накат копий. Дальше — полная копия, затем журналы по порядку, и последний файл с RECOVERY, который выводит базу в онлайн:
RESTORE DATABASE Sales
FROM DISK = N'D:\Backup\Sales_full.bak'
WITH NORECOVERY, REPLACE;
RESTORE LOG Sales
FROM DISK = N'D:\Backup\Sales_log.trn'
WITH NORECOVERY;
-- Последним накатываем хвост журнала и переводим БД в онлайн
RESTORE LOG Sales
FROM DISK = N'D:\Backup\Sales_tail.trn'
WITH RECOVERY;
Нужен откат к моменту до ошибочной операции — используйте восстановление на точку времени вместо RECOVERY на последнем шаге:
RESTORE LOG Sales
FROM DISK = N'D:\Backup\Sales_log.trn'
WITH STOPAT = N'2026-09-18T14:30:00', RECOVERY;
Точка во времени работает только при FULL или bulk-logged модели восстановления; при SIMPLE журнал не хранится и накат на произвольный момент недоступен.
EMERGENCY mode: последняя мера для SUSPECT без бэкапа
Если база помечена SUSPECT, обычной командой к ней не подключиться, а годной резервной копии нет — остается режим EMERGENCY. Он помечает БД как read-only и доступной только членам роли sysadmin: это дает шанс либо выгрузить уцелевшие данные, либо запустить ремонт.
Порядок ниже — разрушающий (REPAIR_ALLOW_DATA_LOSS может удалить данные), поэтому первый шаг — физическая копия файлов, а не команда:
-- ШАГ 0 (вне SQL): скопировать файлы .mdf и .ldf в отдельную папку.
-- Это единственный способ вернуться к исходному состоянию,
-- если ремонт удалит нужное. Не пропускать.
-- ШАГ 1: доступ к поврежденной БД и монопольный режим
ALTER DATABASE Sales SET EMERGENCY;
ALTER DATABASE Sales SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
-- ШАГ 2: сначала оценить масштаб (без ремонта)
DBCC CHECKDB (N'Sales') WITH NO_INFOMSGS, ALL_ERRORMSGS;
-- ШАГ 3: ремонт как крайняя мера. ВНИМАНИЕ: удаляет поврежденные
-- страницы вместе с данными на них - потеря необратима.
DBCC CHECKDB (N'Sales', REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS, ALL_ERRORMSGS;
-- ШАГ 4: вернуть базу пользователям
ALTER DATABASE Sales SET MULTI_USER;
После REPAIR_ALLOW_DATA_LOSS повторно запустите чистый DBCC CHECKDB и убедитесь, что ошибок больше нет. Проверьте бизнес-целостность вручную — ремонт чинит структуру страниц, но не знает про ваши правила: осиротевшие связи и пропавшие строки останутся на вашей совести.
Сторонние утилиты: когда штатных средств мало
Если файл .mdf поврежден настолько, что не подключается, а бэкапа нет, применяют коммерческие утилиты извлечения данных (например, класс инструментов «recovery toolbox для SQL Server»). Они читают сырой файл и выгружают то, что смогли распознать, в скрипт или новую БД. Относитесь к ним как к последнему рубежу после DBCC: работайте только с копией файла, а результат сверяйте с приложением. Точный набор поддерживаемых версий и повреждений зависит от конкретного продукта — это в «Точки для фактчека».
Выводы
- Начинайте не с ремонта, а с диагностики:
sys.databasesдля состояния иDBCC CHECKDBдля целостности; SUSPECT и RECOVERY_PENDING лечатся по-разному. - RECOVERY_PENDING часто снимается устранением ресурсной причины (файл, место, права) и
SET ONLINE, без правки данных. - RESTORE из бэкапа предпочтительнее ремонта: возвращает данные без потерь до точки копии. Перед восстановлением снимайте tail-log backup.
- REPAIR_REBUILD чинит без потери данных; REPAIR_ALLOW_DATA_LOSS удаляет поврежденные страницы и применяется только при отсутствии бэкапа.
- Разрушающий ремонт запускают в EMERGENCY + SINGLE_USER и всегда после копии файлов
.mdf/.ldf; итог проверяют повторным CHECKDB.
Где применяется / связь с практикой
Освойте тему на практике
Диагностика состояний БД, планирование резервных копий и восстановление после сбоя — ежедневные задачи администратора и разработчика SQL Server. На практике важно не просто знать команды, а выстроить порядок: бэкап -> диагностика -> выбор между RESTORE и repair -> проверка результата. Разобрать это на реальных сценариях и стендах помогает курс MS SQL Server. Разработчик: там разбирают внутреннее устройство движка, журналирование и стратегии восстановления. Посмотреть формат и уровень подачи можно на открытых уроках Otus — они бесплатные.
Смежные темы: Особенности резервного копирования баз данных MS SQL, Привилегии в SQL.
FAQ
Можно ли запустить DBCC CHECKDB с REPAIR_REBUILD на рабочей базе без простоя?
Нет. Любой уровень ремонта требует однопользовательского режима (SET SINGLE_USER), то есть на время ремонта база недоступна остальным. Без ремонта, только для проверки, CHECKDB работает и на онлайн-базе.
Что делать, если tail-log backup не снимается из-за поврежденного файла данных?
Добавьте к BACKUP LOG ... WITH NORECOVERY опцию NO_TRUNCATE — она позволяет снять хвост журнала, даже когда основной файл данных недоступен или поврежден, при условии что сам файл журнала цел. Если поврежден уже журнал и NO_TRUNCATE не проходит, вместо нее пробуют CONTINUE_AFTER_ERROR, но такой бэкап уже считается ненадежным.
Почему после REPAIR_ALLOW_DATA_LOSS CHECKDB чистый, а данные все равно неверны?
Ремонт устраняет физические повреждения страниц, но не восстанавливает бизнес-логику: удаленные страницы уносят строки, а внешние ключи и ограничения при этом не пересчитываются. Поэтому после ремонта нужна ручная сверка целостности данных на уровне приложения.



