В практике администрирования распределенных информационных баз (РИБ) иногда возникает критическая ситуация: подчиненный узел начинает «считать», что его конфигурация была изменена, и пытается передать эти изменения в центральную базу (ЦБ). Поскольку архитектура РИБ подразумевает односторонний поток изменений метаданных (только из центра в периферию), центральная база блокирует такой пакет с ошибкой: «Конфигурация не может быть загружена из подчиненного узла». В результате обмен полностью останавливается.
Разберем подробно, почему это происходит и как восстановить работоспособность системы, используя различные методы — от стандартных средств платформы до низкоуровневых манипуляций с базой данных.
Проанализируем ситуацию: платформа 1С:Предприятие отслеживает изменения метаданных с помощью внутренних механизмов регистрации. В норме флаг изменения конфигурации в подчиненном узле может взводиться только при получении сообщения из ЦБ. Однако после некорректных операций (например, выгрузка/загрузка через .dt, аварийное завершение динамического обновления или ошибки в определенных релизах платформы) этот флаг может установиться ошибочно. Платформа начинает видеть «разницу» там, где ее нет, и при формировании файла обмена включает в него заголовок и тело конфигурации.
Первое, что необходимо сделать — это попытаться очистить регистрацию изменений штатным способом. Важно понимать, что очистка изменений по конкретным номерам сообщений здесь может не сработать, так как изменения конфигурации стоят «особняком» в очереди обмена. Рассмотрим программный способ полной очистки регистрации для узла.
Выполним следующий код в подчиненном узле под пользователем с полными правами:
Процедура ПолнаяОчисткаРегистрации(ИмяПланаОбмена, КодУзла)
УзелОбмена = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзла);
Если Не УзелОбмена.Пустая() Тогда
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена);
Сообщить("Регистрация изменений для узла " + КодУзла + " полностью очищена");
КонецЕсли;
КонецПроцедуры
Обратите внимание, что метод УдалитьРегистрациюИзменений без второго параметра Данные должен очищать все изменения, включая метаданные. Однако, как показывает практика, при повреждении системных таблиц этого бывает недостаточно.
Если простая очистка регистрации не помогла, проанализируем более глубокий метод. Нам нужно заставить систему «забыть» о связи с центром, обновить конфигурацию и восстановить связь. Рассмотрим пошагово:
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
.cf) должен быть предварительно выгружен из Центральной Базы. Важно: используйте именно «Загрузить», а не «Сравнить и объединить».
ГлУзел = ПланыОбмена.ВашПланОбмена.НайтиПоКоду("КодЦентральнойБазы");
ПланыОбмена.УстановитьГлавныйУзел(ГлУзел);
Этот метод принудительно синхронизирует структуру таблиц и хэш конфигурации с центральной базой.
Иногда регистрация конфигурации «залипает» из-за незавершенных транзакций в системных таблицах. Посмотрим, как можно «пересчитать» состояние конфигурации простым действием:
Выясним причину через фиктивное изменение. Отвяжите узел от центра (как в Способе 2), добавьте в конфигурацию любой незначащий объект (например, пустой справочник УдалитьМеня) и обновите базу. Затем удалите этот объект и снова обновите базу. После этого восстановите связь с главным узлом. Это действие заставляет платформу полностью перезаписать записи в таблицах изменений метаданных.
Если база клиент-серверная и стандартные методы бессильны, проанализируем структуру базы данных на уровне СУБД. За регистрацию изменений конфигурации в РИБ отвечает системная таблица DBCFGChngRlst.
Внимание: любые действия с SQL-таблицами напрямую являются крайней мерой и требуют обязательного создания резервной копии!
Алгоритм действий для системного администратора:
DELETE FROM DBCFGChngRlst;
Рассмотрим ситуацию, когда информация о необходимости выгрузки конфигурации «застряла» в кэше сервера приложений. Обычная очистка пользовательского кэша (папки в %AppData%) в данном случае не поможет. Требуется полная очистка кэша серверных вызовов.
Для этого необходимо остановить службу 1C:Enterprise 8.3 Server Agent и полностью удалить содержимое папок snccntxt и reg_1541 (за исключением файла 1CV8Reg.lst, если вы не хотите потерять список баз в кластере). После перезапуска службы сервер будет вынужден заново инициализировать параметры планов обмена.
Если центральная база упорно ждет конфигурацию или не принимает пакеты из-за расхождения номеров сообщений, можно сформировать «пустое» сообщение обмена вручную. Это позволит сбросить счетчики и очистить очередь без передачи реальных метаданных.
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Exchange\Message_PБ_ЦБ.xml");
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
УзелЦБ = ПланыОбмена.ВашПланОбмена.НайтиПоКоду("ЦБ");
ЗаписьСообщения.НачатьЗапись(Запись, УзелЦБ);
// Мы не записываем данные и метаданные, просто закрываем сообщение
ЗаписьСообщения.ЗакончитьЗапись();
Запись.Закрыть();
Сформированный таким образом файл будет содержать только заголовок с правильным номером сообщения. При загрузке в ЦБ система увидит, что новых данных нет, и обновит номер принятого сообщения от подчиненного узла, что часто помогает выйти из «замкнутого круга» ошибок.
Подведем итог: чаще всего проблема решается комбинацией Способа 2 (загрузка .cf) и Способа 4 (SQL-запрос). Если же проблема повторяется регулярно, рекомендуем проверить версию платформы 1С — возможно, вы столкнулись с зарегистрированной ошибкой релиза, которая лечится только обновлением платформы до актуальной версии.