Рассмотрим достаточно сложную и неприятную ситуацию, которая может возникнуть при обновлении распределенной информационной базы (РИБ) на базе СУБД PostgreSQL (или MS SQL). При попытке загрузить сообщение обмена с новыми изменениями конфигурации в подчиненный узел, процесс прерывается с критической ошибкой: Ошибка SDBL: Таблица или поле _Fld... не содержится в разделе FROM. При этом в центральной базе и в других подчиненных узлах обновление проходит без проблем.
Разберем детально, почему платформа 1С требует таблицы и поля, которых физически нет ни в конфигурации, ни на уровне СУБД, и проанализируем эффективные способы восстановления работоспособности узла.
Когда вы видите в технологическом журнале или тексте ошибки упоминания полей вида _Fld34480 или таблиц вроде _InfoRG33542NG, вы имеете дело с внутренними идентификаторами 1С на уровне базы данных. Суффикс NG (New Generation) обычно означает, что платформа пытается создать новую структуру таблицы (например, регистра сведений) для последующего переноса в нее данных во время реструктуризации.
Закономерный вопрос: откуда 1С знает о необходимости создания этих таблиц, если в структуре метаданных исходной центральной базы их нет? Разберем этот механизм.
Все соответствия между внутренними идентификаторами метаданных (УИДами объектов конфигурации) и физическими именами таблиц и полей в SQL хранятся в специальной системной таблице Params. Конкретно за это отвечает запись с именем DBNames.
Особенности записи DBNames:
Ошибка возникает из-за того, что в проблемном узле произошло внутреннее рассогласование сопоставления метаданных и имен таблиц/полей БД. Кэш платформы или сама запись DBNames считает, что для реструктуризации определенного объекта требуются поля, которых по факту не существует. Платформа генерирует SQL-запросы на создание этих структур, но спотыкается, когда пытается обратиться к отсутствующим исходным полям.
Многие системные администраторы, отловив проблемный запрос через технологический журнал, пытаются "помочь" платформе и вручную создают требуемые таблицы в PostgreSQL. Посмотрим на пример запроса из логов, на котором спотыкается база:
Sql='drop table if exists _InfoRg33542NG cascade;
create table _InfoRg33542NG (
_Fld33547_TYPE bytea not null,
_Fld33547_RTRef bytea not null,
_Fld33547_RRRef bytea not null,
...
_Fld34480 timestamp not null,
...
) without oids '
Если вы вручную создадите таблицу и добавите недостающее поле _Fld34480, при следующем запуске обмена платформа пройдет этот шаг, но остановится на следующем: она попросит поле _Fld34490, затем _Fld34500 и так далее. Проанализируем причину: вы попадаете в бесконечный цикл. Движок 1С зацикливается, пытаясь сформировать структуру, опираясь на поврежденные данные о метаданных, и будет требовать всё новые и новые поля. Лечить симптомы ручным созданием колонок в СУБД бессмысленно.
Так как проблема кроется глубоко в системных таблицах и кэше сервера 1С, рассмотрим наиболее безопасные и действенные способы решения, которые не требуют прямого вмешательства в бинарные данные SQL.
Этот метод заставляет платформу 1С проигнорировать поврежденные инструкции обмена РИБ и выполнить полную, штатную реструктуризацию на основе эталонной конфигурации из центральной базы (ЦБ). Посмотрим по шагам:
/ResetMasterNode. База перестанет "знать", что она подчиненная..cf)..cf.DBNames в правильном виде, без учета зависших сообщений обмена.
ПланыОбмена.УстановитьГлавныйУзел(ПланыОбмена.[ИмяВашегоПланаОбмена].НайтиПоКоду("КодУзлаЦБ"));
rphost) и обязательно очистите серверный кэш кластера (содержимое папок snccntx). Данные о структурах жестко кэшируются на сервере.Если база весит сотни гигабайт или более терабайта, процессы тестирования и исправления (ТиИ) или полной загрузки .cf могут занять недопустимо много времени (сутки и более). В ситуациях, когда рассогласование зашло в тупик, самым быстрым и гарантированным решением с точки зрения бизнеса часто является пересоздание узла.
Рассмотрим алгоритм действий:
В ходе анализа проблемы может возникнуть идея перенести бинарное содержимое ячейки DBNames из рабочего подчиненного узла в проблемный (через SQL UPDATE). Мы настоятельно не рекомендуем этот подход.
Выясним причину: это сработает только при условии, что внутренние УИДы абсолютно всех объектов метаданных в обеих базах идентичны. Если базы жили долго и переживали разные сбои или динамические обновления в прошлом, УИДы могут отличаться. Подмена DBNames в таком случае приведет к тому, что платформа перепутает таблицы (например, начнет писать данные регистра бухгалтерии в таблицу справочника номенклатуры), что приведет к полному и безвозвратному разрушению информационной базы.