Как исправить ошибку СУБД "RestorePending" (HRESULT=80004005) и восстановить базу данных 1С в копию с помощью SQL-скриптов?

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Внезапное отключение электроэнергии на сервере — страшный сон любого системного администратора и разработчика 1С. Подобные инциденты часто приводят к аппаратным сбоям, рассинхронизации кэша записи дисков и, как следствие, к повреждению структуры базы данных на уровне СУБД. Одним из наиболее неприятных последствий является появление ошибки HRESULT=80004005 SQLSTATE=HY000 Ошибка СУБД: Страница... помечена RestorePending, что может означать повреждение диска.

В этой статье мы подробно разберем природу данной ошибки, проанализируем лог утилиты DBCC CHECKDB, выясним, почему стандартные тесты дисков могут не показывать проблем, а также изучим пошаговое руководство по восстановлению резервной копии в новую базу-копию с помощью T-SQL скриптов в обход ошибок монопольного доступа.

Вместе с вами мы пройдем весь путь спасения данных — от диагностики до успешного развертывания рабочей копии базы.

---

1. Что означает состояние страницы "RestorePending" и почему оно возникает?

Для начала выясним причину возникновения ошибки. Ошибка с кодом HRESULT=80004005 является общим системным сбоем (Unspecified Error), но в контексте MS SQL Server она сопровождается конкретным состоянием страницы базы данных — RestorePending (в терминологии SQL Server это ошибка 829).

База данных MS SQL физически состоит из страниц объемом 8 КБ. Когда СУБД производит чтение или запись, она оперирует именно этими страницами. Если в момент записи данных на диск происходит аварийное отключение питания, процесс прерывается на полуслове. Это явление называется Torn Write (незавершенная или "разорванная" запись).

При последующем обращении к такой странице SQL Server обнаруживает несоответствие контрольных сумм заголовка страницы и ее тела. Чтобы защитить целостность всей остальной базы, СУБД блокирует эту конкретную поврежденную страницу, присваивая ей статус "Ожидание восстановления" (RestorePending).

Важная особенность: в отличие от аварийного режима всей базы данных (SUSPECT), при повреждении отдельных страниц база данных в целом остается в режиме ONLINE. Пользователи могут продолжать работать с другими документами и справочниками. Но как только платформа 1С или регламентное задание попытается обратиться к объекту, данные которого расположены на этой заблокированной странице, СУБД мгновенно вернет ошибку RestorePending и прервет транзакцию.

---

2. Анализируем лог DBCC CHECKDB: Действительно ли проблема в диске?

Зачастую администраторы сомневаются в необходимости замены накопителей, утверждая, что "стандартные тесты дисков ошибок не выявили". Давайте проанализируем фрагменты лога DBCC CHECKDB из нашей практической ситуации, чтобы понять всю серьезность положения:

---

3. Пошаговая инструкция: Восстановление базы данных из бэкапа в копию с помощью T-SQL

Перейдем к решению практической задачи. Автор темы столкнулся с классической проблемой: при попытке восстановить рабочую базу из бэкапа в базу-копию (чтобы не затереть оригинал и провести аудит данных) СУБД выдает ошибку монопольного доступа и сообщает о несовпадении реквизитов (путей размещения файлов).

Разберем, почему это происходит. По умолчанию, при запуске стандартного мастера восстановления в среде SSMS (SQL Server Management Studio), СУБД пытается восстановить файлы данных (.mdf) и лога транзакций (.ldf) по тем путям и с теми именами, которые прописаны внутри самого файла бэкапа (то есть в папки оригинальной рабочей базы). Поскольку оригинальная база в этот момент запущена и файлы заняты, СУБД блокирует операцию.

Мы решим эту задачу красиво и профессионально — с помощью структурированных SQL-запросов. Этот метод работает быстрее, не требует перезапуска служб и полностью исключает человеческий фактор при работе в графическом интерфейсе.

Шаг 1. Получение логических имен файлов из файла резервной копии

Прежде чем перенаправить файлы восстанавливаемой базы в новое место, нам необходимо узнать их внутренние логические имена. Они могут не совпадать с физическими именами файлов на диске. Выполним следующий запрос:


RESTORE FILELISTONLY 
FROM DISK = N'C:\Backup\work_db.bak';

Проанализируем результат выполнения этого запроса. Нам важна колонка LogicalName. Обычно там содержатся две строки:

  1. Логическое имя файла данных (например, work_db).
  2. Логическое имя файла лога транзакций (например, work_db_log).

Запишем или скопируем эти имена — они понадобятся нам на Шаге 3.

Шаг 2. Принудительное отключение активных сессий (монопольный доступ)

Если база-получатель (копия, которую мы назвали, например, work_db_copy) уже создана на сервере, к ней могут быть подключены фоновые процессы, консоль администрирования 1С или сеансы пользователей. Чтобы принудительно разорвать все соединения и перевести базу в монопольный режим, выполним запрос:


USE [master];
ALTER DATABASE [work_db_copy] 
SET SINGLE_USER 
WITH ROLLBACK IMMEDIATE;

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

Шаг 3. Восстановление резервной копии с переносом физических файлов (WITH MOVE)

Теперь выполним основную операцию восстановления. С помощью конструкции MOVE мы переопределим пути физического сохранения файлов .mdf и .ldf, чтобы они не конфликтовали с работающей продакшн-базой. Также мы добавим параметр REPLACE, который разрешает перезаписать существующую базу-копию:


RESTORE DATABASE [work_db_copy] 
FROM DISK = N'C:\Backup\work_db.bak' 
WITH 
  MOVE N'work_db' TO N'C:\SQLData\work_db_copy.mdf', 
  MOVE N'work_db_log' TO N'C:\SQLData\work_db_copy_log.ldf',
  REPLACE, 
  RECOVERY;

Разберем подробнее ключевые параметры этого скрипта:

Шаг 4. Возврат базы данных в многопользовательский режим

После успешного завершения восстановления нам необходимо вернуть базу данных из монопольного режима в штатный многопользовательский, иначе никто, кроме первого подключившегося процесса, не сможет зайти в систему:


ALTER DATABASE [work_db_copy] 
SET MULTI_USER;

Поздравляем! База данных успешно восстановлена в копию под новым именем и полностью готова к работе.

---

4. Специфика повреждения таблиц 1С: Почему бэкап — единственное верное решение?

Давайте проанализируем конкретные таблицы 1С, которые пострадали согласно логу утилиты DBCC CHECKDB:

Почему нельзя использовать автоматическое лечение DBCC CHECKDB с флагом REPAIR_ALLOW_DATA_LOSS?

Многие администраторы совершают фатальную ошибку, пытаясь выполнить команду DBCC CHECKDB ('db', REPAIR_ALLOW_DATA_LOSS) на живой базе. Само название параметра ("разрешить потерю данных") говорит о том, что SQL Server просто удалит поврежденные 8-килобайтные страницы вместе со всеми записями, которые на них находились.

В контексте СУБД база станет "здоровой", но в контексте прикладного решения 1С это обернется катастрофой: удаление страниц в таблице справочника _Reference152 приведет к появлению сотен битых ссылок вида "<Объект не найден>..." в связанных документах и регистрах. База превратится в "решето", восстановить логику учета в которой будет невероятно сложно.

Именно поэтому решение автора форума отказаться от попыток "лечения" поврежденной базы и полностью восстановить ее из актуального чистого бэкапа является единственным методологически верным и безопасным решением для непрерывности бизнеса.

← На главную