Как исправить ошибку СУБД "Страница... помечена RestorePending" и восстановить базу данных SQL из бэкапа?

Системный администратор IT и автоматизация бизнеса
← На главную

Внезапное отключение электроэнергии на сервере — один из злейших врагов систем управления базами данных. При резком прекращении подачи питания незавершенные транзакции и данные в кэше диска могут записаться некорректно, что приводит к разрушению структуры базы данных Microsoft SQL Server. В результате пользователи 1С сталкиваются с аварийным завершением работы, а конфигуратор выдает критическую ошибку:

HRESULT=80004005 SQLSTATE=HY000 Ошибка СУБД: Страница… в базе данных …помечена RestorePending, что может означать повреждение диска.

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

---

Глубокий анализ ошибки и отчета проверки целостности

Состояние RestorePending (ожидание восстановления) присваивается SQL-сервером отдельным страницам данных, если при чтении или записи была обнаружена ошибка ввода-вывода (I/O) либо не прошла проверка контрольной суммы (checksum). СУБД изолирует эти страницы и ожидает, что администратор восстановит их из работоспособной резервной копии.

Проанализируем ключевые сообщения из лога проверки базы данных утилитой DBCC CHECKDB, приведенного в обращении автора:

  1. Ошибки на страницах GAM, SGAM или PFS: Эти страницы являются системными картами распределения пространства в базе данных. Повреждение страниц типа System allocation data блокирует дальнейшую стандартную проверку целостности, так как SQL Server буквально «теряет карту» расположения объектов на диске.
  2. Сообщение 8905 (Экстент помечен как выделенный в GAM, но не распределен...): Указывает на рассогласование метаданных о занятом и свободном месте.
  3. Сообщение 2575 (На страницу карты распределения индекса IAM ссылается указатель... однако страница не обнаружена): Это говорит о разрушении логических цепочек таблиц. СУБД видит ссылку на данные, но самих данных (или карты их размещения) физически не существует. Пострадали как системные таблицы, так и таблицы данных 1С (например, регистры накопления _AccumRgOpt, перечисления _Enum и справочники _Reference).

Если повреждены системные страницы распределения (GAM/SGAM), стандартное лечение базы с помощью команды REPAIR_ALLOW_DATA_LOSS крайне нежелательно, так как это приведет к удалению огромных массивов данных без возможности восстановления. Единственный надежный путь — восстановление из резервной копии.

---

Почему возникает ошибка монопольного доступа при восстановлении?

Часто при попытке восстановить бэкап в копию базы данных администраторы сталкиваются с ошибками монопольного доступа (exclusive lock). Это происходит по двум причинам:

Чтобы избежать этих проблем, разберем чистый и надежный способ восстановления базы через скрипт T-SQL с явным перенаправлением файлов.

---

Инструкция по восстановлению бэкапа в новую базу данных через T-SQL

Выполним процесс восстановления по шагам на языке SQL-запросов. Для работы нам понадобится среда SQL Server Management Studio (SSMS). Откройте ее, нажмите кнопку "Создать запрос" (New Query) и перейдите к выполнению инструкций.

Шаг 1. Определение логических имен файлов внутри бэкапа

В любом файле резервной копии (.bak) хранятся логические имена файлов данных и лога, которые использовались в исходной базе. Нам необходимо их узнать, чтобы перенаправить в новые физические файлы на диске. Выполним команду:


RESTORE FILELISTONLY 
FROM DISK = N'D:\Backups\bgu_backup.bak';

В результате выполнения этого запроса в таблице вы увидите колонку LogicalName. Обычно там содержатся два имени (например, bgu_data и bgu_log). Зафиксируйте эти имена — они понадобятся нам на следующем шаге.

Шаг 2. Написание скрипта восстановления с перемещением (MOVE)

Теперь составим и выполним основной скрипт восстановления. Мы укажем SQL-серверу, что данные нужно развернуть в новую базу (например, bgu_copy), а физические файлы сохранить под новыми именами, чтобы не затереть существующую рабочую базу.


-- Переключаем контекст выполнения на системную базу master
USE [master];
GO

-- Принудительно отключаем всех пользователей от целевой базы, если она существует
IF EXISTS (SELECT name FROM sys.databases WHERE name = N'bgu_copy')
BEGIN
    ALTER DATABASE [bgu_copy] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
END
GO

-- Запуск процедуры восстановления
RESTORE DATABASE [bgu_copy]
FROM DISK = N'D:\Backups\bgu_backup.bak' -- Путь к файлу бэкапа
WITH 
    -- Перемещаем логический файл данных в новый физический файл
    MOVE N'bgu_data' TO N'C:\Program Files\Microsoft SQL Server\MSSQL.Data\bgu_copy.mdf',
    
    -- Перемещаем логический файл лога в новый физический файл
    MOVE N'bgu_log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL.Data\bgu_copy_log.ldf',
    
    -- Разрешаем замену файлов, если база данных с таким именем уже существовала
    REPLACE,
    
    -- Завершаем транзакции и переводим базу в рабочий режим (Online)
    RECOVERY,
    
    -- Выводим прогресс операции каждые 5%
    STATS = 5;
GO

-- Возвращаем многопользовательский режим для новой базы
ALTER DATABASE [bgu_copy] SET MULTI_USER;
GO

Важное примечание: Обязательно замените параметры 'bgu_data' и 'bgu_log' на логические имена, полученные на Шаге 1, а пути к файлам .mdf и .ldf — на актуальные папки вашего SQL-сервера.

---

Что делать, если СУБД ругается на несовпадение реквизитов?

В обсуждении упоминается проблема: «в ту же базу бекап восстановился без проблем, а вот в другую - нет. Что-то про несовпадение реквизитов...».

Такая ошибка возникает, когда метаданные созданной вручную пустой базы данных не совпадают со структурой восстанавливаемого бэкапа. При использовании скрипта T-SQL с параметром REPLACE СУБД полностью перезаписывает структуру целевой базы структурой из бэкапа, поэтому предварительно создавать пустую базу через интерфейс SSMS не требуется — скрипт создаст ее автоматически «на лету».

---

Диагностика оборудования: действительно ли виноват диск?

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

Регулярно настраивайте планы обслуживания в SQL Server для ежедневного резервного копирования и проверки базы данных командой DBCC CHECKDB, чтобы оперативно реагировать на любые признаки аппаратных проблем.

← На главную