Как эффективно очистить регистр сведений в РИБ, не заблокировав обмен данными?

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

В процессе эксплуатации распределенных информационных баз часто возникает проблема «раздувания» регистров сведений. Когда в системе 45 периферийных узлов, стандартное удаление записей через НаборЗаписей приводит к тому, что 1С регистрирует изменения для каждого узла. В итоге объем передаваемых данных при очередном обмене становится критическим, и система «задыхается». Давайте разберем, как справиться с этой задачей грамотно.

Анализ проблемы: почему стандартное удаление «убивает» обмен?

При использовании метода НаборЗаписей.Записать() платформа автоматически создает записи в таблице регистрации изменений плана обмена. Если вы удаляете 12 миллионов записей, для каждого из 45 узлов создается аналогичное количество задач на удаление. Это приводит к блокировкам, росту логов транзакций и зависанию обменов. Чтобы этого избежать, мы должны разделять задачу на два этапа: очистку данных и управление регистрацией изменений.

Шаг 1: Использование программного удаления регистрации

Вместо того чтобы полагаться на автоматическую регистрацию, мы можем самостоятельно управлять тем, что попадает в обмен. Ключевой объект для работы здесь — ПланыОбмена.УдалитьРегистрациюИзменений(). Этот метод позволяет «вычеркнуть» записи из очереди на передачу в конкретный узел.

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


Процедура УдалитьТекущийРегистрациюНаСервере(ТекСегмент)
    // Создаем набор записей для отбора
    Набор = РегистрыСведений.НоменклатураСегмента.СоздатьНаборЗаписей();
    Набор.Отбор.Сегмент.Установить(ТекСегмент);
    
    // Цикл для порционного удаления, чтобы не блокировать таблицу
    ВсеОбработано = Ложь;
    Пока НЕ ВсеОбработано Цикл
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 25000
        |    ИЗМ.Узел, ИЗМ.Сегмент, ИЗМ.Номенклатура, ИЗМ.Характеристика
        |ИЗ РегистрСведений.НоменклатураСегмента.Изменения КАК ИЗМ
        |ГДЕ ИЗМ.Сегмент = &Сегмент";
        
        Запрос.Параметры.Вставить("Сегмент", ТекСегмент);
        Результат = Запрос.Выполнить();
        
        Если Результат.Пустой() Тогда
            ВсеОбработано = Истина;
            Продолжить;
        КонецЕсли;
        
        Выборка = Результат.Выбрать();
        НаборОчистки = РегистрыСведений.НоменклатураСегмента.СоздатьНаборЗаписей();
        
        Пока Выборка.Следующий() Цикл
            НаборОчистки.Отбор.Сегмент.Установить(Выборка.Сегмент);
            НаборОчистки.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
            НаборОчистки.Отбор.Характеристика.Установить(Выборка.Характеристика);
            
            // Удаляем регистрацию для конкретного узла
            ПланыОбмена.УдалитьРегистрациюИзменений(Выборка.Узел, НаборОчистки);
        КонецЦикла;
    КонецЦикла;
КонецПроцедуры

Шаг 2: Порционное удаление данных

Если записей действительно много (миллионы), никогда не пытайтесь удалить их в одной транзакции. Разбейте процесс на порции по 20-50 тысяч записей. Это позволит:

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

Шаг 3: Пересмотр архитектуры обмена

Проанализируйте, действительно ли данные этого регистра должны передаваться в периферийные узлы:

  1. Автономный расчет: Если сегменты номенклатуры могут быть рассчитаны на месте (в каждой ПБ), то лучше вообще исключить этот регистр из состава плана обмена. Это радикально повысит скорость обменов.
  2. Фильтрация: Используйте механизмы подписки на события или правила регистрации, чтобы на периферию уходили только «актуальные» сегменты, необходимые для работы кассового оборудования.
  3. Очистка на точках: В некоторых случаях эффективнее удалить всё содержимое регистра на периферии и прислать из центра только свежие данные, вместо того чтобы пересылать 12 миллионов команд «удалить эту запись».

Важные рекомендации

Перед тем как приступать к массовой чистке, обязательно создайте полную резервную копию. Также помните, что после удаления миллионов записей база данных не уменьшит свой размер автоматически. Вам потребуется выполнить сжатие (Shrink) таблиц в СУБД или провести процедуру тестирования и исправления с реиндексацией, чтобы вернуть производительность системы в норму.

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

← На главную