Почему возникает ошибка SDBL «Таблица или поле не содержится в разделе FROM» при загрузке в подчиненный узел РИБ и как ее исправить?

Системный администратор 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Рассмотрим достаточно сложную и неприятную ситуацию, которая может возникнуть при обновлении распределенной информационной базы (РИБ) на базе СУБД PostgreSQL (или MS SQL). При попытке загрузить сообщение обмена с новыми изменениями конфигурации в подчиненный узел, процесс прерывается с критической ошибкой: Ошибка SDBL: Таблица или поле _Fld... не содержится в разделе FROM. При этом в центральной базе и в других подчиненных узлах обновление проходит без проблем.

Разберем детально, почему платформа 1С требует таблицы и поля, которых физически нет ни в конфигурации, ни на уровне СУБД, и проанализируем эффективные способы восстановления работоспособности узла.

Суть проблемы: рассинхронизация метаданных и физической структуры

Когда вы видите в технологическом журнале или тексте ошибки упоминания полей вида _Fld34480 или таблиц вроде _InfoRG33542NG, вы имеете дело с внутренними идентификаторами 1С на уровне базы данных. Суффикс NG (New Generation) обычно означает, что платформа пытается создать новую структуру таблицы (например, регистра сведений) для последующего переноса в нее данных во время реструктуризации.

Закономерный вопрос: откуда 1С знает о необходимости создания этих таблиц, если в структуре метаданных исходной центральной базы их нет? Разберем этот механизм.

Все соответствия между внутренними идентификаторами метаданных (УИДами объектов конфигурации) и физическими именами таблиц и полей в SQL хранятся в специальной системной таблице Params. Конкретно за это отвечает запись с именем DBNames.

Особенности записи DBNames:

  1. Она содержит список структур, описывающих объекты хранения данных (основные таблицы, таблицы настроек, поля и т.д.).
  2. Данные в этой ячейке хранятся не в открытом текстовом виде, а сжаты по алгоритму Deflate (бинарный формат).
  3. Прямое сравнение или редактирование этой записи средствами СУБД без предварительной распаковки (Inflate) невозможно.

Ошибка возникает из-за того, что в проблемном узле произошло внутреннее рассогласование сопоставления метаданных и имен таблиц/полей БД. Кэш платформы или сама запись DBNames считает, что для реструктуризации определенного объекта требуются поля, которых по факту не существует. Платформа генерирует SQL-запросы на создание этих структур, но спотыкается, когда пытается обратиться к отсутствующим исходным полям.

Почему ручное вмешательство в SQL (DDL) не помогает?

Многие системные администраторы, отловив проблемный запрос через технологический журнал, пытаются "помочь" платформе и вручную создают требуемые таблицы в 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: Отвязка от главного узла и принудительная реструктуризация (Рекомендуемый)

Этот метод заставляет платформу 1С проигнорировать поврежденные инструкции обмена РИБ и выполнить полную, штатную реструктуризацию на основе эталонной конфигурации из центральной базы (ЦБ). Посмотрим по шагам:

  1. Создание бэкапа: Обязательно сделайте резервную копию проблемного узла (средствами СУБД или выгрузкой dt).
  2. Отвязка узла РИБ: Проблемную базу необходимо временно сделать независимой. Для этого запустите 1С:Предприятие (Конфигуратор) с параметром командной строки /ResetMasterNode. База перестанет "знать", что она подчиненная.
  3. Получение эталона: Из центральной базы выгрузите файл конфигурации (в формате .cf).
  4. Загрузка конфигурации: В конфигураторе проблемной (теперь независимой) базы выполните "Сравнение и объединение" или "Загрузку конфигурации из файла", выбрав полученный .cf.
  5. Реструктуризация: Нажмите F7 (Обновить конфигурацию базы данных). В этот момент платформа выполнит корректный пересчет всех структур метаданных и самостоятельно перезапишет таблицу DBNames в правильном виде, без учета зависших сообщений обмена.
  6. Привязка обратно: Восстановите связь с главным узлом. Это можно сделать небольшой обработкой с кодом:
    
    ПланыОбмена.УстановитьГлавныйУзел(ПланыОбмена.[ИмяВашегоПланаОбмена].НайтиПоКоду("КодУзлаЦБ"));
    
  7. Очистка кэша: Остановите службу сервера 1С (rphost) и обязательно очистите серверный кэш кластера (содержимое папок snccntx). Данные о структурах жестко кэшируются на сервере.
  8. Запустите сеанс и выполните обмен РИБ. Ошибка должна уйти.

Способ 2: Создание нового начального образа (Для больших баз)

Если база весит сотни гигабайт или более терабайта, процессы тестирования и исправления (ТиИ) или полной загрузки .cf могут занять недопустимо много времени (сутки и более). В ситуациях, когда рассогласование зашло в тупик, самым быстрым и гарантированным решением с точки зрения бизнеса часто является пересоздание узла.

Рассмотрим алгоритм действий:

  1. В центральной базе создается новый начальный образ для данного филиала.
  2. Старая проблемная база выводится из эксплуатации.
  3. Разворачивается новый образ.
  4. Если в поврежденном узле оставались непереданные данные (документы, созданные пользователями), их можно перенести в центральную базу с помощью обработок переноса данных (через XML или правила конвертации) до удаления старой базы, а затем они придут в новый узел при первом штатном обмене.

Почему не стоит копировать DBNames из другой базы?

В ходе анализа проблемы может возникнуть идея перенести бинарное содержимое ячейки DBNames из рабочего подчиненного узла в проблемный (через SQL UPDATE). Мы настоятельно не рекомендуем этот подход.

Выясним причину: это сработает только при условии, что внутренние УИДы абсолютно всех объектов метаданных в обеих базах идентичны. Если базы жили долго и переживали разные сбои или динамические обновления в прошлом, УИДы могут отличаться. Подмена DBNames в таком случае приведет к тому, что платформа перепутает таблицы (например, начнет писать данные регистра бухгалтерии в таблицу справочника номенклатуры), что приведет к полному и безвозвратному разрушению информационной базы.

← На главную