Как отключить регистрацию изменений для отдельного узла РИБ без его удаления?

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

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

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

Способ 1. Выборочное исключение узла из состава получателей при записи

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

В платформе 1С при включенной авторегистрации перед выполнением обработчика события ПередЗаписью коллекция Объект.ОбменДанными.Получатели автоматически заполняется всеми узлами соответствующего плана обмена. Если удалить нужный узел из этой коллекции до фиксации транзакции, платформа физически не создаст запись в таблице регистрации изменений для этого узла.

Для реализации этого метода выполним следующие шаги:

  1. Создадим общую подписку на событие ПередЗаписью для необходимых типов объектов (или определим обработчик в расширении конфигурации, если основная конфигурация находится на поддержке).
  2. В процедуре обработчика получим ссылку на «замороженный» узел плана обмена.
  3. Удалим данный узел из коллекции получателей перед сохранением объекта.

Посмотрим на пример кода процедуры подписки на событие:


Процедура ИсключитьЗамороженныйУзелПередЗаписью(Источник, Отказ) Экспорт
    
    // Получаем ссылку на проблемный узел плана обмена
    УзелОтключен = ПланыОбмена.Филиалы.НайтиПоКоду("Филиал_Склад");
    
    Если ЗначениеЗаполнено(УзелОтключен) Тогда
        // Проверяем наличие узла в коллекции и удаляем его
        СтрокаПолучателя = Источник.ОбменДанными.Получатели.Найти(УзелОтключен);
        Если СтрокаПолучателя <> Неопределено Тогда
            Источник.ОбменДанными.Получатели.Удалить(СтрокаПолучателя);
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

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

Способ 2. Автоматическая периодическая очистка регистрации регламентным заданием

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

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


Процедура ОчиститьРегистрациюПоУзлу() Экспорт
    
    УзелДляОчистки = ПланыОбмена.Филиалы.НайтиПоКоду("Филиал_Склад");
    
    Если ЗначениеЗаполнено(УзелДляОчистки) Тогда
        // Полное удаление всех накопленных изменений по выбранному узлу
        ПланыОбмена.УдалитьРегистрациюИзменений(УзелДляОчистки);
    КонецЕсли;

КонецПроцедуры

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

Способ 3. Разовая ручная очистка перед пересозданием узла

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


УзелОбмена = ПланыОбмена.Филиалы.НайтиПоНаименованию("Филиал Север");
Если ЗначениеЗаполнено(УзелОбмена) Тогда
    ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена);
КонецЕсли;

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

Особенности файловых баз и освобождение дискового пространства

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

Чтобы физически уменьшить размер файла базы после массовой очистки регистрации изменений, необходимо:

  1. Запустить конфигуратор в монопольном режиме.
  2. Открыть меню Администрирование > Тестирование и исправление...
  3. Выбрать режим Сжатие таблиц информационной базы и нажать кнопку Выполнить (либо воспользоваться утилитой chdbfl.exe).

После этой процедуры неиспользуемые страницы таблиц будут удалены, и размер файла базы данных существенно сократится.

← На главную