Внезапное отключение электроэнергии на сервере — один из злейших врагов систем управления базами данных. При резком прекращении подачи питания незавершенные транзакции и данные в кэше диска могут записаться некорректно, что приводит к разрушению структуры базы данных Microsoft SQL Server. В результате пользователи 1С сталкиваются с аварийным завершением работы, а конфигуратор выдает критическую ошибку:
HRESULT=80004005 SQLSTATE=HY000 Ошибка СУБД: Страница… в базе данных …помечена RestorePending, что может означать повреждение диска.
В этой статье мы подробно разберем природу данной ошибки, проанализируем отчет утилиты DBCC CHECKDB, а также пошагово рассмотрим процесс корректного восстановления базы данных из резервной копии (бэкапа) в новую базу с помощью языка запросов T-SQL (Transact-SQL), минуя стандартный графический визард СУБД.
---
Состояние RestorePending (ожидание восстановления) присваивается SQL-сервером отдельным страницам данных, если при чтении или записи была обнаружена ошибка ввода-вывода (I/O) либо не прошла проверка контрольной суммы (checksum). СУБД изолирует эти страницы и ожидает, что администратор восстановит их из работоспособной резервной копии.
Проанализируем ключевые сообщения из лога проверки базы данных утилитой DBCC CHECKDB, приведенного в обращении автора:
System allocation data блокирует дальнейшую стандартную проверку целостности, так как SQL Server буквально «теряет карту» расположения объектов на диске._AccumRgOpt, перечисления _Enum и справочники _Reference).Если повреждены системные страницы распределения (GAM/SGAM), стандартное лечение базы с помощью команды REPAIR_ALLOW_DATA_LOSS крайне нежелательно, так как это приведет к удалению огромных массивов данных без возможности восстановления. Единственный надежный путь — восстановление из резервной копии.
---
Часто при попытке восстановить бэкап в копию базы данных администраторы сталкиваются с ошибками монопольного доступа (exclusive lock). Это происходит по двум причинам:
.mdf) и лога транзакций (.ldf).Чтобы избежать этих проблем, разберем чистый и надежный способ восстановления базы через скрипт T-SQL с явным перенаправлением файлов.
---
Выполним процесс восстановления по шагам на языке SQL-запросов. Для работы нам понадобится среда SQL Server Management Studio (SSMS). Откройте ее, нажмите кнопку "Создать запрос" (New Query) и перейдите к выполнению инструкций.
В любом файле резервной копии (.bak) хранятся логические имена файлов данных и лога, которые использовались в исходной базе. Нам необходимо их узнать, чтобы перенаправить в новые физические файлы на диске. Выполним команду:
RESTORE FILELISTONLY
FROM DISK = N'D:\Backups\bgu_backup.bak';
В результате выполнения этого запроса в таблице вы увидите колонку LogicalName. Обычно там содержатся два имени (например, bgu_data и bgu_log). Зафиксируйте эти имена — они понадобятся нам на следующем шаге.
Теперь составим и выполним основной скрипт восстановления. Мы укажем 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 не требуется — скрипт создаст ее автоматически «на лету».
---
Пользователи часто отмечают, что стандартные тесты диска в консоли ОС не показывают ошибок (бэд-блоков нет), и считают это гарантией исправности накопителя. Однако СУБД работает с дисковой подсистемой на совершенно другом уровне. Проанализируем возможные аппаратные причины сбоя:
MemTest86.Регулярно настраивайте планы обслуживания в SQL Server для ежедневного резервного копирования и проверки базы данных командой DBCC CHECKDB, чтобы оперативно реагировать на любые признаки аппаратных проблем.