Представим ситуацию: на сервере произошел внезапный сбой питания (Power Failure), а после перезагрузки попытка войти в 1С:Предприятие заканчивается критической ошибкой: «FATAL: catalog is missing 1 attribute(s) for relid 2662». Ситуация осложняется тем, что резервные копии могли оказаться повреждены или недоступны. В этой статье мы подробно разберем, что означает эта ошибка, почему она возникает и какие шаги необходимо предпринять, чтобы попытаться спасти данные и вернуть базу в рабочее состояние.
Для начала проанализируем техническую суть сообщения. В PostgreSQL каждая таблица, индекс или представление имеют свой уникальный идентификатор — OID (Object Identifier). Число 2662 жестко зарезервировано в ядре СУБД за системной таблицей pg_class.
Таблица pg_class — это «сердце» системного каталога. В ней хранится информация о структуре всех остальных таблиц базы данных 1С. Сообщение о том, что в каталоге «не хватает атрибута», означает физическое повреждение данных на диске. Скорее всего, произошла так называемая «неполная запись» (torn page): в момент отключения питания сервер записывал изменения в системный каталог, и часть данных была утеряна или записана некорректно. Теперь структура таблицы pg_class в файлах данных не совпадает с тем, что ожидает увидеть программный код PostgreSQL при запуске сессии.
Прежде чем приступать к любым восстановительным работам, проанализируем текущее состояние файлов. Ни в коем случае не пытайтесь проводить эксперименты на «живой» базе, которая только что пострадала.
services.msc).data (в нашем примере это D:\PostgreSQL\data\) на другой физический диск или сетевой ресурс.Выясним, не менялась ли версия исполняемых файлов PostgreSQL. Часто системные администраторы пытаются «переустановить» сервер после сбоя. Если вы установили версию, отличную от той, на которой база была создана (например, переход с ванильного PostgreSQL на сборку от Postgres Pro или 1С), системный каталог может выдать ошибку 2662 из-за внутренних различий в структуре pg_class между редакциями. Убедитесь, что бинарные файлы (папка bin) в точности соответствуют версии данных.
Поскольку стандартное подключение через psql или консоль 1С невозможно, рассмотрим вариант запуска сервера в режиме «одного пользователя». В этом режиме СУБД позволяет выполнять административные действия в обход многих стандартных проверок.
Для запуска откроем командную строку от имени администратора и перейдем в каталог с исполняемыми файлами. Попробуем запустить процесс вручную:
cd /d "C:\Program Files\PostgreSQL\13\bin"
postgres.exe --single -D "D:\PostgreSQL\data" имя_вашей_базы
Если сервер запустился и выдал приглашение для ввода команд, это хороший знак. Попробуем выполнить переиндексацию системных таблиц, так как ошибка может крыться не в самих данных, а в поврежденном индексе таблицы pg_class:
REINDEX SYSTEM имя_вашей_базы;
После завершения операции введите CTRL+D или CTRL+Z для выхода и попробуйте запустить службу в обычном режиме.
Если однопользовательский режим не помог, проанализируем возможность игнорирования системных индексов. Для этого нам нужно внести изменения в файл конфигурации postgresql.conf, который находится в папке data.
postgresql.conf текстовым редактором.ignore_system_indexes = on.Этот параметр заставляет СУБД читать системные таблицы напрямую, не обращаясь к индексам. Если база запустится, необходимо немедленно выполнить выгрузку данных. Используем утилиту pg_dump для создания бэкапа:
pg_dump.exe -h localhost -U postgres -F c -b -v -f "D:\backup_recovery.backup" имя_базы
Важно: после успешной выгрузки этот параметр нужно обязательно вернуть в off, а базу — пересоздать из полученного дампа.
Если повреждение затронуло сами страницы данных pg_class, сервер может аварийно завершать работу при попытке чтения. В этом случае рассмотрим применение параметра zero_damaged_pages.
Установим в postgresql.conf значение:
zero_damaged_pages = on
При обнаружении битой страницы (Checksum failure или Torn page), PostgreSQL заполнит ее нулями и продолжит работу. Это приведет к потере части системной информации (например, пропадет запись о какой-то таблице или индексе), но позволит серверу стартовать и даст вам шанс выгрузить те данные, которые уцелели.
Поскольку причиной сбоя послужило питание, файлы в папке pg_wal (или pg_xlog в старых версиях) могут быть рассинхронизированы с файлами данных. Если сервер отказывается запускаться даже после вышеописанных мер, можно применить «хирургическое» вмешательство — утилиту pg_resetwal.
Внимание: это действие может привести к потере целостности данных, так как оно принудительно очищает журналы транзакций и переписывает контрольную точку.
pg_resetwal.exe -f "D:\PostgreSQL\data"
После выполнения этой команды сервер «забудет» о незавершенных транзакциях и попытается открыться «как есть».
Проанализировав ситуацию, мы понимаем, что даже если нам удалось запустить PostgreSQL, база может находиться в логически несогласованном состоянии. Для полноценного восстановления 1С рекомендуем следующий алгоритм:
ignore_system_indexes или zero_damaged_pages), сделайте pg_dump..dt и загрузите её в еще одну чистую базу. Это окончательно очистит структуру данных от возможных «фантомов» битого системного каталога.Помните, что ошибка системного каталога — это серьезный сигнал к проверке аппаратной части сервера. Проверьте состояние дисков (S.M.A.R.T.) и обязательно настройте регулярное резервное копирование на внешние носители, чтобы избежать подобных трудозатратных процедур в будущем. Для организации такой защиты данных можно использовать решение для создания резервных копий баз PostgreSQL по схеме 3-2-1-1-0.