Как решить проблемы с обменом в распределенной базе данных (РИБ) 1С: восстановление конфигурации, синхронизация номеров сообщений и устранение битых ссылок?

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

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

В этой статье мы подробно рассмотрим, как восстановить работоспособность РИБ после подобных сбоев, разберем алгоритм синхронизации номеров сообщений, выясним особенности регистрации связанных данных и поймем физическую природу появления и устранения битых ссылок со статусом <Объект не найден>.

Шаг 1. Восстановление конфигурации подчиненного узла при рассинхронизации

Когда конфигурация подчиненного (периферийного) узла начинает расходиться с конфигурацией главного узла, платформа блокирует обмен данными. Попытка загрузить очередное сообщение обмена заканчивается ошибкой. Чтобы исправить эту ситуацию, нам необходимо временно «отвязать» подчиненный узел от главного, принудительно залить в него эталонную конфигурацию и восстановить связь. Разберем этот процесс по шагам.

Для начала нам нужно снять признак подчиненности узла. Выполним это программно в режиме «1С:Предприятие» в подчиненной базе с помощью следующего кода:


// Отключаем главный узел в подчиненной базе данных
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
Сообщить("Связь с главным узлом успешно разорвана. База переведена в автономный режим.");

Альтернативным способом «отвязки» базы является запуск Конфигуратора через командную строку операционной системы с использованием специального ключа. Для этого закройте базу и выполните следующую команду:

1cv8.exe ENTERPRISE /F "ПутьКВашейБазе" /ResetMasterNode

После того как узел стал автономным, выполним следующие действия в Конфигураторе периферийной базы:

  1. Выгрузите эталонную конфигурацию из главного узла в файл (меню Конфигурация -> Сохранить конфигурацию в файл..., на выходе получим файл с расширением .cf).
  2. В подчиненном узле откройте Конфигуратор и перейдите в меню Конфигурация -> Загрузить конфигурацию из файла.... Выберите сохраненный ранее файл .cf. Важно: используйте именно «Загрузить конфигурацию», а не «Сравнить/объединить», чтобы полностью сопоставить внутренние идентификаторы (DBID) двух баз.
  3. Обновите конфигурацию базы данных, нажав клавишу F7.

После успешного обновления конфигурации нам необходимо вернуть узел в состав РИБ. Запустите подчиненную базу в режиме «1С:Предприятие» и выполните программный код для привязки главного узла:


// Находим ссылку на главный узел и устанавливаем его обратно
ИмяПланаОбмена = "Полный"; // Укажите имя вашего плана обмена
КодГлавногоУзла = "ГЛ";    // Укажите код главного узла в вашей системе

СсылкаНаУзел = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодГлавногоУзла);

Если ЗначениеЗаполнено(СсылкаНаУзел) Тогда
    ПланыОбмена.УстановитьГлавныйУзел(СсылкаНаУзел);
    Сообщить("Главный узел успешно назначен. База снова находится в РИБ."); Иначе
    ВызватьИсключение "Не удалось найти узел с указанным кодом!";
КонецЕсли;

Обратите внимание на расширения конфигурации: начиная с платформы версии 8.3.12, расширения могут синхронизироваться автоматически. Если при попытке привязать узел обратно вы получаете ошибку о конфликте расширений, временно удалите все засинхронизированные расширения в подчиненном узле. При первом же успешном сеансе обмена платформа загрузит их из главного узла автоматически.

Шаг 2. Выравнивание и синхронизация номеров сообщений

После отката баз или сбоев конфигурации счетчики номеров отправленных и принятых сообщений в планах обмена перестают совпадать, что вызывает ошибку трансляции пакетов. Для возобновления обмена номера сообщений в карточках узлов должны строго соответствовать формуле:

Корректировку счетчиков можно выполнить с помощью стандартной обработки «Регистрация изменений для обмена данными» (вкладка «Параметры доставки») или написать простой программный сценарий, который принудительно выставит нужные значения в узле плана обмена:


// Программная корректировка номеров сообщений обмена
УзелОбъект = СсылкаНаУзел.ПолучитьОбъект();
УзелОбъект.НомерОтправленного = 150; // Установите актуальный номер отправленного
УзелОбъект.НомерПринятого = 149;     // Установите актуальный номер принятого
УзелОбъект.Записать();
Сообщить("Счетчики сообщений успешно скорректированы.");

Шаг 3. Повторная регистрация изменений и связанных данных

Проанализируем частую проблему: из-за сбоя часть подтвержденных данных «выпала» из очереди отправки, но фактически не дошла до главного узла. Нам нужно зарегистрировать эти изменения повторно. Но как сделать это правильно, чтобы не получить пустые ссылки в базе-приемнике?

Выясним ключевую особенность платформы 1С. Загрузка данных при обмене всегда происходит в специальном режиме: ОбменДанными.Загрузка = Истина. Это означает следующее:

Если мы зарегистрируем к обмену только сам документ (например, документ «Реализация товаров и услуг»), то в базу-приемник перенесется исключительно шапка документа и его табличные части. Движения по регистрам накопления останутся пустыми или устаревшими! Чтобы этого избежать, мы должны зарегистрировать к обмену весь комплекс связанных данных.

Рассмотрим, как правильно зарегистрировать данные через встроенную обработку «Регистрация изменений для обмена данными»:

  1. Запустите обработку в вашей базе данных.
  2. Найдите нужный тип документа, настройте отбор (например, по периоду или конкретному контрагенту) и зарегистрируйте выбранные документы.
  3. Перейдите к связанным регистрам накопления и сведений (например, «Товары на складах», «Продажи»). Настройте аналогичные отборы по регистратору и зарегистрируйте наборы записей этих регистров.
  4. Для независимых регистров сведений (где нет регистратора) регистрация выполняется по измерениям регистра.

Не беспокойтесь о дублировании данных: при повторной загрузке документов или записей регистров в базу-приемник платформа выполнит поиск по уникальному идентификатору (GUID) или по ключевым полям измерений регистров. Все старые данные будут просто перезаписаны актуальными значениями, двоения записей не произойдет.

Шаг 4. Устранение битых ссылок типа <Объект не найден> и механизм их «оживления»

Допустим, мы перенесли документ «Касса», внутри которого содержится табличная часть со ссылками на документы «Приходный кассовый ордер» (ПКО). Если сами документы ПКО не были зарегистрированы и отправлены в главную базу, на месте этих полей мы увидим надпись вида: <Объект не найден> (84:bf56ea1234...). Разберем по шагам, почему это происходит и как это исправить.

Проанализируем физическое устройство базы данных на уровне СУБД (например, MS SQL или PostgreSQL). В таблице документа «Касса» в колонке, отвечающей за ПКО, хранится не название документа и не его номер. Там записан чистый 128-битный уникальный идентификатор (GUID/UUID) — например, 84bf56ea-1234-5678-90ab-cdef12345678.

Когда пользователь открывает форму документа «Касса», платформа 1С делает динамический запрос к таблице ПКО, пытаясь найти строку с этим GUID, чтобы прочитать дату и номер для отображения красивого представления. Если в таблице ПКО такой строки нет, платформа генерирует строковое представление по умолчанию: <Объект не найден> и указывает в скобках шестнадцатеричный код этого GUID.

Как решить эту проблему? Нам достаточно просто зарегистрировать недостающие документы ПКО в подчиненном узле и выгрузить их в главную базу. Ссылка «оживет» сама собой!

Когда выгруженный файл XML с документами ПКО загружается в главную базу, платформа считывает GUID каждого ПКО и создает в таблице ПКО новые записи именно с этими идентификаторами. При следующем открытии документа «Касса» платформа снова делает запрос по GUID, успешно находит запись ПКО и выводит пользователю корректный номер и дату. Сам документ «Касса» при этом изменять, перепроводить или перезаписывать не требуется.

Если битых ссылок в вашей базе слишком много, мы рекомендуем использовать встроенный инструмент Конфигуратора «Тестирование и исправление». В нем доступны два режима работы с битыми ссылками:

Шаг 5. Работа с уникальными идентификаторами (GUID) и метод УстановитьСсылкуНового()

Рассмотрим подробнее природу GUID в 1С. Платформа использует стандарт UUID версии 1 (RFC 4122) с доработками. Количество возможных комбинаций составляет $2^{128}$ (примерно $3.4 \times 10^{38}$ предметов). Вероятность того, что в двух разных базах случайно сгенерируются абсолютно одинаковые GUID для документов одного типа, стремится к нулю. Поэтому коллизии при стандартной генерации исключены.

Однако коллизия может случиться из-за человеческого фактора. Например, если подчиненный узел РИБ создали не штатным методом («Создать начальный образ»), а простым копированием файла базы данных. В этом случае все GUID документов в обеих базах изначально идентичны, и при обмене они начнут затирать друг друга.

В процессе интеграции или исправления данных иногда возникает необходимость программно создать объект с заранее известным GUID. Для этого используется метод УстановитьСсылкуНового(). Посмотрим на практический пример реализации этого метода:


// Создание нового документа с принудительным назначением конкретного GUID
НовыйДокумент = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();

// Преобразуем строковое представление GUID в объект УникальныйИдентификатор
СтрокаGUID = "84bf56ea-1234-5678-90ab-cdef12345678";
НужныйИдентификатор = Новый УникальныйИдентификатор(СтрокаGUID);

// Получаем ссылку на будущий документ на основе этого GUID
НоваяСсылка = Документы.ПриходныйКассовыйОрдер.ПолучитьСсылка(НужныйИдентификатор);

// Устанавливаем ссылку для нового, еще не записанного объекта
НовыйДокумент.УстановитьСсылкуНового(НоваяСсылка);

// Заполняем обязательные реквизиты документа
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7700000000");
НовыйДокумент.СуммаДокумента = 1500;

// Записываем документ в базу данных
Попытка
    НовыйДокумент.Записать();
    Сообщить("Документ успешно записан с GUID: " + НовыйДокумент.Ссылка.УникальныйИдентификатор());
Исключение
    Сообщить("Ошибка при записи документа: " + ОписаниеОшибки());
КонецПопытки;

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

← На главную