Рано или поздно любой администратор баз данных или специалист 1С сталкивается с ситуацией, когда при выполнении регламентных операций или при попытке изменить документ в системе СУБД аварийно завершает работу, выдавая пугающие сообщения о повреждении физической структуры. Одной из таких критических ошибок является ошибка СУБД Microsoft SQL Server с кодом Msg 8909 (incorrect page ID in page header).
В этой статье мы подробно разберем, почему возникает эта ошибка на стыке платформы 1С и MS SQL Server, почему временный успех её «лечения» через пересоздание индексов может быть обманчивым, как провести глубокую диагностику аппаратной части сервера и какие профилактические меры навсегда защитят вашу базу данных от потери информации.
Проанализируем детально системное сообщение, которое выдает утилита DBCC CHECKDB при обнаружении сбоя:
Msg 8909, Level 16, State 1. Table error: Object ID 55983576, index ID 2, partition ID 72057602218786816, alloc unit ID 72057602120679424 (type In-row data), page ID (1:586349) contains an incorrect page ID in its page header. The PageId in the page header = (1:1897069).
Давайте расшифруем эту информацию по шагам, чтобы понять логику работы СУБД:
_Seq10300. Префикс _Seq обозначает таблицу регистрации последовательности документов. Последовательности используются для контроля хронологии проведения документов (например, в партионном учете или при расчете взаиморасчетов). Число 10300 — это внутренний идентификатор метаданных этой последовательности.index ID 2 критически важно для понимания тяжести проблемы. В архитектуре MS SQL Server принята строгая иерархия индексов:
index ID 0 — это «куча» (heap, таблица без кластерного индекса);index ID 1 — это кластерный индекс (само тело таблицы, где физически лежат строки с данными);index ID >= 2 — это некластеризованные (вторичные) индексы, которые представляют собой лишь упорядоченные указатели на строки кластерного индекса.index ID 1, простое пересоздание индексов завершилось бы сбоем, и потребовалось бы восстановление базы из бэкапа или исправление с потерей данных (команда REPAIR_ALLOW_DATA_LOSS).Текст ошибки «contains an incorrect page ID in its page header» означает буквально следующее: SQL Server обратился к файлу базы данных, рассчитывая прочитать страницу с физическим адресом 1:586349. Однако, считав 96-байтный заголовок этой страницы из памяти или с диска, он обнаружил, что там записан совсем другой адрес — 1:1897069.
В архитектуре баз данных это классический маркер серьезных проблем дисковой подсистемы. Выделим три основные физические причины происходящего:
Рассмотрим подробнее, как действовать, если вы столкнулись с подобной ошибкой в вашей базе данных 1С.
Если проверка DBCC CHECKDB выявила повреждение именно во вторичном индексе (ID >= 2), мы можем быстро вернуть базу в рабочее состояние без остановки работы пользователей на длительное время. Для этого выполним регенерацию индексов поврежденной таблицы.
Запустим SQL Server Management Studio (SSMS), откроем новый запрос к нашей базе данных и выполним команду пересборки всех индексов для таблицы _Seq10300:
USE [Имя_Вашей_Базы_1С];
GO
ALTER INDEX ALL ON [_Seq10300] REBUILD;
GO
После успешного выполнения команды запустим повторную проверку целостности, чтобы убедиться, что ошибки согласованности исчезли:
DBCC CHECKDB ([Имя_Вашей_Базы_1С]) WITH NO_INFOMSGS;
GO
Если в выводе команды мы увидим сообщение об отсутствии ошибок распределения и согласованности, значит, оперативное восстановление прошло успешно. Однако расслабляться рано.
Как справедливо отмечают опытные специалисты, база данных просто так не рушится. Если проблема носит аппаратный характер, она обязательно вернется. В следующий раз повреждение может затронуть не индекс, а саму таблицу с данными (кластерный индекс), что приведет к безвозвратной потере документов или справочников.
Выясним причину сбоя, выполнив три диагностических действия:
1. Анализ системных логов на ошибки 823, 824 и 825.
Нам необходимо открыть SQL Server Error Log и журнал событий Windows (раздел «Система»). Особое внимание уделим поиску ошибки 825 (Read-Retry). Эта скрытая ошибка указывает на то, что SQL Server не смог прочитать страницу с диска с первого раза, но после нескольких повторных попыток чтение все-таки удалось. Ошибка 825 записывается в лог как информационное предупреждение, работа базы при этом не прерывается, но она является самым главным предвестником скорого выхода из строя диска или RAID-контроллера.
2. Запрос к таблице suspect_pages.
В системной базе данных msdb существует служебная таблица, куда SQL Server автоматически заносит сведения о страницах, при обращении к которым возникали аппаратные проблемы. Проанализируем состояние этой таблицы, выполнив запрос:
SELECT
database_id,
file_id,
page_id,
event_type,
error_count,
last_update_date
FROM msdb.dbo.suspect_pages;
Значения в колонке event_type расшифровываются следующим образом:
1 — Ошибка 823, связанная с аппаратным сбоем (например, битый сектор);2 — Ошибка проверки контрольной суммы (Bad Checksum);3 — Ошибка разорванной страницы (Torn Page);4 — Страница восстановлена (например, средствами зеркалирования или из бэкапа).Если в этой таблице есть записи с кодами 1, 2 или 3 — ваша дисковая подсистема находится под угрозой, и диски требуют немедленной замены.
3. Аппаратная проверка RAID-контроллера.
Обычная утилита CHKDSK в данной ситуации малоэффективна, так как она проверяет только логическую файловую систему NTFS, но не видит физических проблем секторов под RAID-массивом. Нам необходимо открыть специализированную утилиту управления вашим RAID-контроллером (например, HPE Smart Storage Administrator (SSA), LSI Storage Authority, Dell OpenManage и т.д.) и проверить логи на наличие «мягких» ошибок чтения (Media Errors), сбоев четности или предупреждений о скором отказе накопителя (Predictive Failure).
Чтобы минимизировать риски и оперативно узнавать о подобных сбоях до того, как база окончательно разрушится, настроим систему превентивной защиты.
1. Включение CHECKSUM для страниц данных.
В свойствах базы данных 1С (раздел Options в SSMS) параметр Page Verify должен быть установлен в значение CHECKSUM. В старых базах, перенесенных со старых версий SQL Server, там по умолчанию может стоять устаревший режим TORN_PAGE_DETECTION или NONE. Режим CHECKSUM заставляет SQL Server рассчитывать контрольную сумму страницы при каждой записи на диск и сверять её при каждом чтении. Это позволяет обнаружить порчу данных мгновенно, не дожидаясь регламентного запуска проверок.
Изменить этот параметр можно скриптом:
ALTER DATABASE [Имя_Вашей_Базы_1С] SET PAGE_VERIFY CHECKSUM WITH NO_WAIT;
GO
2. Резервное копирование с проверкой контрольных сумм.
Настроим регулярное создание резервных копий с обязательным флагом WITH CHECKSUM. Если в базе появится скрытая поврежденная страница, процесс создания бэкапа прервется с ошибкой, и администратор сразу узнает о проблеме. Это предотвратит критическую ситуацию, когда поврежденная база успешно резервируется изо дня в день, затирая старые «здоровые» копии.
Пример скрипта для создания бэкапа с проверкой:
BACKUP DATABASE [Имя_Вашей_Базы_1С]
TO DISK = N'D:\Backup\Base1C.bak'
WITH CHECKSUM, INIT, STATS = 10;
GO
3. Регламентные проверки DBCC CHECKDB.
Настроим регулярное автоматическое задание (SQL Server Agent Job), которое будет запускать полную проверку целостности базы данных DBCC CHECKDB по расписанию (например, каждую ночь или раз в неделю) перед процедурой резервного копирования.
4. Внедрение стратегии исторического резервирования.
Не путайте оперативные бэкапы (создаваемые каждые несколько часов для минимизации простоев при аварии) и исторические архивы. Ошибка в базе данных может оставаться незамеченной неделями и даже месяцами, если пользователи не обращаются к поврежденным старым записям. Если у вас хранятся только оперативные копии за последние 3-5 дней, вы рискуете остаться с набором бэкапов, каждый из которых уже содержит ошибку. Обязательно храните архивные копии базы данных за каждый месяц, квартал и год на независимом сетевом хранилище.