Приветствуем вас, коллеги! Сегодня мы детально разберем крайне опасную и сложную техническую ситуацию, с которой может столкнуться любой системный администратор или специалист по сопровождению баз данных 1С. Представьте картину: после очередного сбоя питания или проблем с дисковым массивом пользователи не могут войти в 1С, выгрузка информационной базы через Конфигуратор завершается аварийно, а стандартная проверка СУБД прерывается на полуслове. Ситуация усугубляется тем, что актуального регулярного бэкапа под рукой нет — только копия месячной давности.
Проанализируем детально системную ошибку, выясним глубинную причину ее возникновения, поймем, почему стандартные средства восстановления баз данных отказываются работать, и рассмотрим практические шаги по спасению уцелевшей информации.
Для начала давайте внимательно изучим лог проверки базы данных, который предоставил администратор после выполнения команды DBCC CHECKDB. СУБД возвращает следующие критические сообщения:
Сообщение 7985, уровень 16, состояние 2, строка 1: Предварительная проверка системных таблиц: объект с идентификатором 7. Не удалось прочитать страницу (1:159524) и заблокировать ее кратковременной блокировкой типа SH. Инструкция проверки прервана из-за неустранимой ошибки.
Сообщение 5233, уровень 16, состояние 98, строка 1: Ошибка в таблице. Идентификатор единицы распределения 458752, страница (1:159524). Проверка (IS_OFF (BUF_IOERR, pBUF->bstat)) не пройдена.
Разберем эти параметры на составляющие, чтобы понять масштаб проблемы:
sys.sysallocunits (таблица единиц распределения). Данная таблица является фундаментом логической структуры базы данных: она хранит карту соответствия всех физических страниц на диске конкретным таблицам, индексам и метаданным вашей базы 1С.BUF_IOERR прямо указывает на то, что физический диск или контроллер вернули поврежденный блок данных либо не смогли его прочитать вовсе.sys.sysallocunits, SQL Server физически теряет карту размещения данных. Он больше не знает, где начинаются и заканчиваются таблицы 1С (такие как справочники _Reference или документы _Document). Из-за этого СУБД не может продолжить сканирование и аварийно прерывает работу. По этой же причине любые попытки запустить восстановление с параметрами REPAIR_FAST, REPAIR_REBUILD или даже разрушительным REPAIR_ALLOW_DATA_LOSS завершаются неудачей — СУБД просто не доходит до этапа ремонта пользовательских таблиц.Очень часто администраторы допускают логическую ошибку, рассуждая следующим образом: "Я сделал бэкап в формате .bak, перенес его на другой сервер, развернул там, но ошибка осталась. Значит, диски на исходном сервере исправны, проблема в самой программе".
Давайте проанализируем эту ситуацию. СУБД при создании резервной копии методом BACKUP DATABASE производит последовательное постраничное копирование данных из файла .mdf в файл резервной копии .bak. Если на исходном сервере страница 1:159524 уже была записана с ошибками (из-за сбоя контроллера RAID, "посыпавшихся" магнитных секторов HDD или деградации ячеек SSD), СУБД скопирует эти битые байты "как есть".
В итоге, разворачивая этот бэкап на абсолютно новом, исправном оборудовании, мы получаем ту же самую картину: поврежденные метаданные разворачиваются в новую базу, и SQL Server снова спотыкается о нечитаемую системную страницу. Исходная причина повреждения практически со 100% вероятностью носит аппаратный характер (проблемы с дисками, памятью, контроллером или питанием на исходном сервере), а перенос битого бэкапа лишь зафиксировал эту неисправность.
Поскольку встроенные средства автоматического исправления SQL Server бессильны перед разрушением таблицы sys.sysallocunits, рассмотрим альтернативные варианты спасения информационной базы 1С.
Если ваша база данных работала в модели восстановления Full (Полная) и у вас помимо сегодняшнего поврежденного бэкапа есть предыдущий целый бэкап (например, недельной давности) и непрерывная цепочка резервных копий логов транзакций (файлов .trn), мы можем точечно восстановить только одну поврежденную страницу.
Выполним по шагам следующие действия в среде SQL Server Management Studio (SSMS):
Шаг 1. Переведем базу данных в режим восстановления поврежденной страницы, указав ее точный адрес:
RESTORE DATABASE [basenew] PAGE = '1:159524'
FROM DISK = 'C:\Backup\Full_Good_Backup.bak'
WITH NORECOVERY;
Шаг 2. Последовательно накатим всю цепочку последующих бэкапов журналов транзакций, включая самый последний бэкап лога, сделанный непосредственно перед аварией (Tail-Log Backup):
RESTORE LOG [basenew]
FROM DISK = 'C:\Backup\Log_Backup_1.trn'
WITH NORECOVERY;
RESTORE LOG [basenew]
FROM DISK = 'C:\Backup\Log_Tail.trn'
WITH RECOVERY;
Если цепочка логов цела, СУБД успешно заменит поврежденную страницу ее чистой копией и "докатит" все транзакции до момента сбоя. База будет спасена без потери данных. Если же использовалась модель восстановления Simple (Простая), данный метод применить невозможно.
Если восстановить страницу через бэкапы логов не получается, попробуем перевести базу данных в специальный аварийный режим EMERGENCY. Этот режим заставляет СУБД игнорировать критические ошибки разметки метаданных и открывает базу исключительно на чтение.
Переведем базу данных в аварийный однопользовательский режим:
ALTER DATABASE [basenew] SET EMERGENCY;
ALTER DATABASE [basenew] SET SINGLE_USER;
После успешного перехода базы в режим EMERGENCY, СУБД попытается предоставить доступ к тем таблицам, чьи страницы распределения не задеты физическим повреждением. Теперь наша задача — вытащить максимальное количество информации. Для этого выполним следующие действия:
.dt).basenew, а в качестве приемника — новую пустую базу.1:159524, скопировать не удастся (процесс завершится ошибкой), но все остальные таблицы (справочники, константы, большая часть документов) будут успешно перенесены в новую базу.Поскольку у нас на руках есть выгрузка информационной базы 1С месячной давности (где гарантированно цела вся конфигурация и логическая структура метаданных), мы можем использовать гибридный подход для минимизации потерь информации.
Рассмотрим алгоритм действий подробнее:
.dt. Назовем ее "Эталонная база".EMERGENCY (как описано в Варианте Б) и запустить к ней доступ через платформу 1С:Предприятие в режиме "Только чтение". Если конфигурация запускается, это огромная удача.Если СУБД наотрез отказывается запускать базу даже в режиме EMERGENCY, единственным выходом остается использование специализированного программного обеспечения, которое работает с файлом данных .mdf напрямую, минуя движок MS SQL Server.
Такие программные продукты (например, *Stellar Repair for MS SQL*, *Recovery Toolbox for SQL Server* или *SysTools SQL Recovery*) сканируют двоичную структуру файла данных, находят заголовки таблиц 1С и собирают уцелевшие записи "по кусочкам". Они способны восстановить структуру базы данных и выгрузить информацию в виде SQL-скриптов для генерации новой базы или записать данные напрямую в чистую СУБД. Это платное ПО, но в условиях отсутствия свежих резервных копий оно зачастую является единственным шансом спасти бизнес от полной остановки.
Проанализировав данную проблему, важно сделать правильные организационные выводы. Не зря в сообществе системных администраторов шутят, что все специалисты делятся на тех, кто еще не делает бэкапы, тех, кто их уже делает регулярно, и самый редкий подвид — тех, кто эти бэкапы регулярно проверяет.
Чтобы больше никогда не оказаться в ситуации, когда база разрушена, а последней архивной копии больше месяца, внедрим в свою работу три простых правила:
DBCC CHECKDB.