При активной разработке и поддержке нетиповых или сильно кастомизированных конфигураций 1С программисты часто сталкиваются с операциями изменения метаданных. Одной из самых ресурсоемких и непредсказуемых по времени операций является изменение состава субконто на счетах учета в регистре бухгалтерии. В некоторых случаях на относительно небольших базах (объемом 10–15 ГБ) этот процесс может затянуться на десятки часов или даже суток, тогда как на огромных базах объемом более 100 ГБ аналогичное обновление проходит за пару часов.
В этой статье мы подробно разберем, почему возникает эта проблема на уровне СУБД и платформы 1С, проанализируем физический смысл происходящих процессов и рассмотрим проверенную практическую методику, которая позволяет сократить время реструктуризации регистра бухгалтерии с десятков часов до получаса.
Когда мы изменяем виды субконто у счета в конфигураторе, платформа 1С:Предприятие инициирует процедуру полной реструктуризации таблиц регистра бухгалтерии. Чтобы понять, почему этот процесс работает медленно, заглянем «под капот» взаимодействия платформы и СУБД (например, MS SQL Server):
_NG (например, _AccRgED..._NG для таблицы значений субконто). Затем сервер 1С начинает считывать данные из старой таблицы порциями и построчно записывать их в новую таблицу, попутно выполняя приведение типов данных. Для больших таблиц (даже на 10–15 миллионов записей) этот процесс создает колоссальное количество мелких транзакций._AccRgAT0 до _AccRgAT3) забиваются так называемыми нулевыми остатками. Это строки, в которых в разрезе счета и субконто конечный остаток на конец месяца равен нулю, но сама запись физически присутствует в базе. При реструктуризации платформа вынуждена пересчитывать, конвертировать и переносить все эти миллионы «мусорных» строк, тратя на это колоссальное время.Для решения этой проблемы мы применим проверенный административный алгоритм. Его суть заключается в том, чтобы временно освободить СУБД от необходимости обрабатывать миллионы строк в таблицах итогов во время реструктуризации, а затем рассчитать эти итоги заново в оптимизированном пакетном режиме.
Рассмотрим этот процесс подробно и разберем его по шагам:
Хотя все операции можно выполнять непосредственно на MS SQL Server, для полной гарантии отсутствия блокировок со стороны других сессий и процессов рекомендуется выгрузить информационную базу в файл резервной копии (формат .dt) и развернуть её локально в файловом варианте. Как показывает практика, на локальном SSD-накопителе в файловом варианте этот метод отрабатывает так же эффективно.
Перед началом каких-либо изменений метаданных нам необходимо зафиксировать состояние базы и временно отключить использование текущих итогов по проблемному регистру бухгалтерии. Это заставит платформу игнорировать оперативные итоги при последующих манипуляциях.
Для этого мы можем использовать обработку или выполнить следующий код во внешнем соединении или в режиме «1С:Предприятие»:
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеТекущихИтогов(Ложь);
Это самый важный шаг всего алгоритма. Нам необходимо установить период рассчитанных итогов регистра бухгалтерии на дату, которая предшествует самой первой проводке в нашей базе данных. Например, если учет в базе ведется с 2015 года, мы установим период итогов на 01.01.2000 года.
Сделать это можно интерактивно через меню «Администрирование» — «Управление итогами» в режиме «1С:Предприятие», выбрав нужный регистр и установив период рассчитанных итогов назад в прошлое.
Программный аналог этой операции выглядит следующим образом:
МоментВПрошлом = '20000101000000';
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодРассчитанныхИтогов(МоментВПрошлом);
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Ложь);
Физический смысл операции: Когда платформа 1С получает команду установить период рассчитанных итогов на дату, где еще нет движений, она выполняет команду очистки таблиц (аналогичную TRUNCATE TABLE в SQL) для всех физических таблиц итогов регистра (_AccRgAT0, _AccRgAT1 и т.д.). Все строки из этих таблиц мгновенно удаляются. Таблицы итогов становятся абсолютно пустыми!
Теперь мы открываем базу данных в режиме «Конфигуратор», вносим необходимые изменения в субконто счетов и запускаем обновление конфигурации базы данных (клавиша F7) или запускаем процедуру «Тестирование и исправление» (ТиИ) с единственным выбранным пунктом — «Реструктуризация таблиц информационной базы».
Поскольку таблицы итогов теперь абсолютно пусты, платформе больше не нужно считывать, конвертировать и записывать миллионы строк итогов. Она реструктурирует исключительно основную таблицу движений регистра (_AccRg), что занимает минимум времени. Процесс реструктуризации на этом этапе сокращается в десятки раз.
После успешного завершения реструктуризации и обновления конфигурации нам необходимо вернуть систему в рабочее состояние. Для этого мы заходим в режим «1С:Предприятие» и возвращаем период рассчитанных итогов на исходную рабочую дату (например, на конец текущего месяца).
Программно мы выполняем следующий код:
КонецТекущегоМесяца = КонецМесяца(ТекущаяДата());
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Истина);
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеТекущихИтогов(Истина);
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодРассчитанныхИтогов(КонецТекущегоМесяца);
При выполнении этой команды платформа 1С выполнит полный расчет итогов с нуля. Почему это будет работать быстро? Потому что расчет итогов с нуля реализован разработчиками платформы как массовая векторная SQL-операция (используются пакетные запросы INSERT INTO ... SELECT ...). СУБД выполняет такой расчет за один проход, задействуя механизмы параллелизма и оптимизации планов запросов. Это в десятки раз быстрее, чем построчный пересчет и корректировка итогов в процессе изменения схемы данных.
В результате этих несложных манипуляций общее время реструктуризации базы данных автора темы сократилось с 24 часов до 30 минут!
Если вышеописанный метод по каким-то причинам не дал желаемого ускорения, проанализируем дополнительные факторы, которые могут влиять на производительность операций СУБД при работе с регистрами бухгалтерии.
Начиная с версии платформы 8.3.11, разработчики 1С добавили новый, оптимизированный механизм реструктуризации баз данных (версия 2). В отличие от старого механизма, версия v2 переносит практически всю нагрузку по трансформации таблиц непосредственно на СУБД, избегая построчной передачи данных на сервер приложений 1С.
Для включения этого механизма должны быть выполнены следующие условия:
JAVA_HOME должна указывать на корректный каталог JRE/JDK).conf.cfg должен быть прописан параметр, разрешающий использование нового механизма. Для этого добавьте в файл строку:
DbmsRedefinition=v2
Использование механизма реструктуризации v2 позволяет значительно сократить время изменения метаданных на СУБД MS SQL Server и PostgreSQL за счет выполнения пакетных операций копирования данных внутри СУБД.
Одной из частых причин зависания реструктуризации является неактуальная статистика оптимизатора MS SQL Server. Если статистика устарела, SQL-сервер строит неверный план выполнения запроса, выбирая сканирование всей таблицы вместо использования подходящих индексов.
Перед запуском тяжелых обновлений обязательно выполните принудительное обновление статистики для вашей базы данных в SQL Server Management Studio (SSMS) с помощью следующего запроса:
USE [ИмяВашейБазыДанных];
EXEC sp_updatestats;
Это гарантирует, что оптимизатор запросов СУБД будет владеть актуальной информацией о распределении данных в таблицах регистра бухгалтерии.
При выполнении пересчета итогов СУБД пытается распараллелить операцию расчета на все доступные ядра процессора. Однако при неверных настройках сервера это может приводить к взаимным блокировкам потоков (ожидания типа CXPACKET).
Для тяжелых регламентных операций рекомендуется временно установить параметр максимальной степени параллелизма (MAXDOP) в значение 2 или 4 (в зависимости от архитектуры вашего процессора). Это позволит СУБД эффективно распараллеливать вычисления, не создавая при этом избыточных задержек на синхронизацию потоков.
Применяя данные методики и понимая внутреннее устройство хранения данных в 1С, вы сможете с легкостью администрировать даже самые высоконагруженные базы данных и выполнять их обновление в кратчайшие сроки.