Всем доброго дня! При подготовке обновления для перехода с версии ДП 2.5.17 на версию 2.5.22 (Комплексная автоматизация) столкнулся у одного клиента с двумя не очень приятными моментами:
- Долгая регистрация объектов для отложенного обновления (на тестовом контуре 2 часа)
- И совсем уж неприемлемо долгая процедура выполнения обработчиков отложенного обновления (на все том же тестовом контуре - 8 часов)
Все нижеследующие "махинации" применимы для всего семейства УТ/КА/ERP.
В ходе недолгих разбирательств была найдена причина в лице многим знакомого (в плохом смысле этого слова))) регистра сведений "РеестрДокументов". Что же именно произошло?
- В релизах ХХ.5.20 в этот регистр сведений 1С добавила новое измерение - ИдентификаторЗаписи
- При обновлении на релиз ХХ.5.20 и выше происходит регистрация на плане обмена ОбновлениеИнформационнойБазы всех записей регистра с пустым измерением ИдентификаторЗаписи
- В процессе отложенного обновления происходит заполнение этого измерения значением Строка(Новый УникальныйИдентификатор)
Соответственно, чем больше в базе документов, тем дольше будет выполняться обновление базы данных. В рассматриваемой базе регистр сведений имел 1.4 млн записей:
- регистрация изменений на плане обмена занимала в среднем 1.5 часа
- отложенная обработка - 8 часов в режиме приоритета обновления и больше двух суток в режиме приоритета работы пользователей (помним, что база тестовая и по факту пользователей там не работало все это время).
Первое, что пришло на ум - это как-то попытаться ускорить процесс регистрации изменений. Дело в том, что 1С по умолчанию регистрирует изменения порциями по 1000 объектов. В данном случае (несколько упрощенно):
- Выбирает все различные значения измерения Ссылка
- Создает набор записи с отбором по измерению Ссылка
- Добавляет набор в массив текущей порции
- Отправляет массив на регистрацию: если порция содержит 1000 элементов - порция регистрируется и массив очищается, если порция меньше 1000 элементов - цикл пополнения порции продолжается
- Если после всего цикла в порции остаются элементы, то производиться принудительная регистрация оставшихся наборов записей.
Попробовав различные размеры порций, стало понятно: сколь-нибудь значимого прироста скорости я не получу. Поэтому я перешел сразу к радиальному решению.
По факту мы видим, что новое измерение явно является техническим, его заполнения не зависит от состояния информационной базы, а список необработанных записей мы легко можем получить в любой момент и он также не зависит от состояния прочих объектов. Поэтому сразу напрашивается вариант - взять заполнение данного регистра в свои руки. А это сразу означает, что я сэкономлю 1.5 часа, если при обновлении базы данных не буду регистрировать записи на плане обмена. Процедура регистрации располагается в модуле менеджера регистра сведений "РеестрДокументов". Я решил заимствовать его в расширение с директивой &ИзменениеИКонтроль (на случай, если забуду удалить после обновления и что-то 1С поменяет))
Следующая, более значительная проблема заключается в том, что собственно заполнение нового измерения происходит более 6 часов. Заполнение, судя по отладчику, также происходит порциями по 1000 записей. Причем 1С сначала подготавливает потоки обновления, записывает служебную информацию, запускает их в отдельных фоновых заданиях и контролирует их выполнение.
Я решил пойти по другому пути и разбить порции по периодам. Поскольку учет ведется с начала 2020 года, было выделено несколько периодов:
- До 31.12.2019 - преимущественно по регистраторам расчетов, которые использовались при вводе начальных остатков
- По каждому последующему году
- С начала 2025 года и далее без ограничения (если что-то ввели будущей датой)
Далее в уже имеющееся расширение добавил серверный модуль с одной процедурой.
Процедура предназначена для заполнения нового измерения по записям в заданном периоде. Также добавил небольшое логирование в журнал регистрации.
И остается, что называется, "на коленке" подготовить код для запуска нескольких фоновых заданий по каждому из периодов. Например, можно подготовить внешнюю обработку с одной кнопкой на форме. Примитивно код запуска 7 фоновых заданий будет иметь вид (можно вбить в консоль кода):
Запускал эти обработчики параллельно с другими отложенными обработчиками. В итоге 1.4 млн записей были обработаны за 2 часа и 6 минут, а весь процесс отложенного обновления занял 3.5 часа вместо исходных 6 часов
Что можно сделать еще? Если вы уверены, что пользователи работают с документами только в определенном периоде, то можно в монопольном режиме перезаполнить записи в "рабочем периоде", после чего уже можно запускать пользователей и параллельно запустить обновление оставшихся записей. Но здесь нужно дополнительно анализировать, на что и как влияет новое измерение, если оно не заполнено.
Вступайте в нашу телеграмм-группу Инфостарт