Перевод информационных баз 1С:Предприятия на СУБД PostgreSQL — один из самых популярных сценариев при импортозамещении и оптимизации затрат на лицензирование. Однако многие системные администраторы и разработчики при первом тестировании сталкиваются с неприятным сюрпризом: производительность PostgreSQL «из коробки» на операционной системе Windows оказывается значительно ниже, чем у MS SQL Server. В некоторых случаях разница в скорости выполнения критических операций, таких как проведение документов, может достигать двух и более раз.
В этой статье мы подробно разберем, почему возникает такая разница в производительности, проанализируем влияние операционной системы на работу СУБД, рассмотрим узкие места платформы 1С и пошагово настроим PostgreSQL для достижения максимальной скорости работы.
Для начала выясним причину, по которой «ванильный» (стандартный) PostgreSQL показывает скромные результаты сразу после установки. Разработчики PostgreSQL изначально ориентируют стандартные настройки конфигурации на минимальные системные требования. СУБД по умолчанию сконфигурирована так, чтобы запуститься практически на любом «железе», потребляя минимум оперативной памяти (около 128–512 МБ). MS SQL Server, напротив, динамически захватывает практически всю доступную оперативную память сервера и оптимизирует свои процессы под текущие аппаратные мощности в автоматическом режиме.
Кроме того, архитектура планировщика и оптимизатора запросов MS SQL Server исторически более эффективно обрабатывает сложные, многократно вложенные запросы со множеством соединений виртуальных таблиц, которые генерирует платформа 1С. PostgreSQL требует более точной настройки параметров стоимости операций, чтобы правильно строить планы выполнения таких запросов.
Рассмотрим важный архитектурный аспект. PostgreSQL исторически разрабатывался под Unix-подобные операционные системы. В Linux используется fork-модель управления процессами, которая работает крайне быстро и эффективно. Портирование PostgreSQL на операционную систему Windows выполнено через эмуляцию некоторых функций, и СУБД вынуждена использовать потоки Windows (threads) внутри одного процесса, что накладывает определенные ограничения на масштабируемость и скорость работы с памятью.
Еще одна серьезная проблема кроется в сетевом обмене между сервером приложений 1С (процессом rphost) и СУБД:
Поэтому перенос СУБД PostgreSQL на Linux (например, Ubuntu, CentOS, RedOS или Astra Linux) сам по себе дает прирост производительности в районе 20–30% за счет более эффективной работы с памятью, файловой системой и локальными сокетами.
Часто при анализе производительности СУБД администраторы замечают, что во время длительного перепроведения документов процессор сервера загружен всего на 10–12%. Выясним причину этого явления. Проведение конкретного документа в 1С (или запуск пакетного проведения в рамках одной сессии) всегда выполняется в один поток. Один поток может утилизировать на 100% только одно логическое ядро процессора.
Если на вашем сервере установлен процессор с 8 ядрами (или 16 потоками с учетом Hyper-Threading), то теоретический максимум загрузки процессора одним потоком проведения составляет всего 6,25% – 12,5%. В данном случае узким местом становится не СУБД сама по себе, а тактовая частота одного ядра процессора и скорость работы СУБД с временными таблицами. Для таких задач критически важно выбирать процессоры с высокой частотой на одно ядро (например, Intel Core i7 / i9 или современные процессоры AMD Ryzen с частотой выше 4.5 ГГц в режиме Turbo Boost), а также использовать максимально быстрые диски NVMe.
Перейдем к практическому тюнингу параметров СУБД. Все изменения мы будем вносить в конфигурационный файл postgresql.conf. Ориентируемся на сервер со следующими характеристиками: 8-ядерный процессор, 32 ГБ оперативной памяти DDR4 и дисковая подсистема на быстрых SSD NVMe в RAID-массиве.
Рассмотрим подробнее ключевые параметры, которые необходимо изменить.
Для эффективного кэширования данных и оптимизации работы с временными таблицами установим следующие параметры:
shared_buffers = 8GB # Устанавливаем 25% от общего объема ОЗУ (32 ГБ). На Windows не рекомендуется ставить выше 8-10 ГБ из-за особенностей работы с памятью.
temp_buffers = 256MB # 1С активно использует временные таблицы. Увеличение этого параметра до 128-256 МБ позволит обрабатывать их в оперативной памяти без сброса на диск.
work_mem = 128MB # Объем памяти для сортировок и группировок в рамках одного запроса. Если запросы сложные, СУБД будет делать это в памяти.
maintenance_work_mem = 2GB # Память для сервисных операций (индексация, очистка VACUUM). Позволит ускорить регламентные процедуры.
Стандартные настройки планировщика рассчитаны на медленные диски HDD. Если СУБД размещена на быстрых SSD NVMe, планировщик должен об этом знать, иначе он будет строить неоптимальные планы, избегая индексного сканирования. Настроим параметры стоимости операций:
random_page_cost = 1.1 # Для SSD дисков стоимость случайного доступа почти равна последовательному. По умолчанию стоит 4.0.
seq_page_cost = 1.0 # Базовая стоимость последовательного чтения.
effective_cache_size = 24GB # Оценка общего объема памяти, доступного для кэширования файлов (примерно 75% от всей ОЗУ сервера). Помогает планировщику точнее оценивать шансы нахождения данных в кэше.
Для ускорения операций записи и проведения документов крайне важна настройка сброса транзакций на диск. По умолчанию включен жесткий режим синхронизации, когда каждая транзакция ожидает физической записи на диск:
synchronous_commit = off # Отключаем жесткую синхронизацию транзакций. Запись будет идти в буфер WAL, а на диск сбрасываться асинхронно (раз в доли секунды). Это дает кратный прирост скорости проведения документов. Риск потери данных минимален и ограничивается транзакциями за последние 0.5-1 сек в случае аварийного отключения питания сервера.
wal_buffers = 16MB # Размер буфера для незаписанных данных WAL. При включении асинхронного коммита этот буфер должен быть заполнен оптимально.
checkpoint_completion_target = 0.9 # Размазывает процесс записи контрольной точки во времени, снижая пиковую нагрузку на диски.
checkpoint_timeout = 15min # Увеличиваем интервал между контрольными точками, чтобы снизить частоту интенсивных дисковых операций записи.
max_wal_size = 4GB # Разрешаем накапливать больший объем логов транзакций перед принудительным чекпоинтом.
В процессе работы 1С постоянно создает, обновляет и удаляет миллионы временных записей. В PostgreSQL при изменении или удалении строки старая версия физически остается на диске («мертвая строка»). Если их вовремя не очищать, таблицы начинают «раздуваться» (bloat), а скорость выполнения запросов резко падает. Настройки автовакуума по умолчанию слишком ленивы для 1С. Сделаем очистку более частой и агрессивной:
autovacuum = on # Обязательно должен быть включен!
autovacuum_max_workers = 4 # Количество одновременно работающих процессов очистки.
autovacuum_naptime = 20s # Интервал времени, через который запускается проверка таблиц на необходимость очистки.
autovacuum_vacuum_scale_factor = 0.05 # Запускать очистку таблицы, если в ней изменилось или удалилось более 5% строк (по умолчанию 20%).
autovacuum_analyze_scale_factor = 0.02 # Запускать сбор статистики, если изменилось более 2% строк таблицы.
autovacuum_vacuum_cost_limit = 1000 # Увеличиваем лимит стоимости операций очистки, чтобы автовакуум не засыпал слишком быстро при высокой активности.
Для СУБД PostgreSQL, используемой совместно с 1С, критически важна установка специализированных расширений, поставляемых в дистрибьюторах от самой компании 1С или Postgres Pro:
online_analyze: Это расширение заставляет СУБД мгновенно пересчитывать статистику распределения данных во временных таблицах сразу после их заполнения. Без этого планировщик PostgreSQL строит план выполнения запроса «вслепую», полагая, что во временной таблице либо 0 строк, либо 1000 строк (по умолчанию), что приводит к зависанию тяжелых отчетов и алгоритмов проведения.plantuner: Помогает планировщику СУБД корректно подбирать индексы для таблиц 1С, отключая использование некоторых неэффективных сканирований.Убедитесь, что данные расширения прописаны в параметре shared_preload_libraries в файле postgresql.conf:
shared_preload_libraries = 'online_analyze, plantuner'
После внесения изменений в конфигурационный файл обязательно перезапустите службу PostgreSQL для применения настроек.
Проанализируем результаты проделанной работы. При первоначальном запуске теста производительности (например, популярного теста Гилева) на «чистом», ненастроенном PostgreSQL на Windows показатели могут находиться в районе 15–18 попугаев. В то же время MS SQL на аналогичном железе без труда выдает 40–45 попугаев.
После выполнения тонкой настройки конфигурационного файла postgresql.conf (изменение параметров памяти, отключение synchronous_commit, оптимизация стоимости операций под SSD) производительность PostgreSQL в тесте Гилева вырастает до 40–43 попугаев, практически полностью сравниваясь с показателями MS SQL Server.
При этом, если мы замерим время проведения сложного пакета документов (как в примере автора темы — около 19 000 документов), мы увидим, что общая скорость проведения вырастет благодаря оптимизации записи на диск и ускорению работы с временными таблицами. Однако окончательный паритет будет достигнут только при переносе СУБД на операционную систему Linux, где накладные расходы на межпроцессное взаимодействие минимальны.
Выяснив причины низкой производительности СУБД, мы можем сформулировать ключевые правила успешного внедрения PostgreSQL для баз данных 1С:
shared_buffers, temp_buffers), дисковых операций (synchronous_commit = off) и автовакуума — обязательный шаг.