PostgreSQL 9.3 под 1С 8.3: конфиг для 50 пользователей
Разворачивали 1С 8.3 на PostgreSQL 9.3 вместо MS SQL - специальная сборка от 1С, патч для русской локали и настройка shared_buffers. Публикуем рабочий конфиг.
PostgreSQL как альтернатива MS SQL для 1С 8.3 становится реальным вариантом в условиях импортозамещения
Один из клиентов - организация с мягкими признаками госсектора - пришёл с задачей: перевести рабочую базу 1С 8.3 с MS SQL Server на PostgreSQL. Не потому что хочется, а потому что импортозамещение давит сверху, а лицензии MS SQL дорогие и переоформляются болезненно. Мы к этому готовились ещё с июльского обзора отечественного ПО, где PostgreSQL фигурировал как основной кандидат на замену. Теперь потрогали руками.
Честное предупреждение: это не «поставили и заработало». Здесь три отдельных подводных камня, и каждый требует понимания что происходит, а не просто копипасты конфига.
Сборка PostgreSQL - только от 1С
Первый и самый важный момент: стандартный PostgreSQL из репозиториев здесь не работает. Фирма 1С поддерживает собственную сборку PostgreSQL 9.3 с патчами под специфику платформы. Называется «Postgres Pro» в их терминологии - на деле это PostgreSQL 9.3 с набором патчей от 1С, которые правят поведение блокировок и некоторых типов данных под то, как платформа 8.3 генерирует запросы.
Берётся с партнёрского портала 1С - публично не лежит. Если у клиента действующая партнёрская программа, доступ есть. Мы взяли RPM-пакет под RHEL/CentOS 6 - это наш стандартный серверный стек.
Патч для русской локали
После установки сборки создание базы данных для 1С требует конкретного шаблона:
CREATE DATABASE my1c
TEMPLATE template0
ENCODING 'UTF8'
LC_COLLATE 'ru_RU.UTF-8'
LC_CTYPE 'ru_RU.UTF-8';
Проблема в том, что ru_RU.UTF-8 по умолчанию на CentOS даёт сортировку через glibc, а у glibc и PostgreSQL есть исторически нетривиальные отношения именно с кириллическими локалями. Проявляется это в некорректной сортировке текстовых полей в некоторых запросах 1С - на первый взгляд незаметно, но в отчётах вылезает.
Решение, которое нам помогло: убедиться что locale-gen отработал честно, locale -a показывает нужную локаль, и создавать базу именно через template0 - не template1. Второй момент: в /etc/locale.conf (CentOS 7) или /etc/sysconfig/i18n (CentOS 6) должно быть LANG=ru_RU.UTF-8, и после перезапуска PostgreSQL подхватывает это из окружения.
postgresql.conf для 50 пользователей
Вот здесь большая часть работы. Дефолтные настройки PostgreSQL написаны для машины с 256 МБ RAM образца десятилетней давности - под нагрузку 1С они не годятся. Сервер у клиента: 2 x Intel Xeon E5-2620, 32 ГБ RAM, RAID-10 на SAS.
Рабочий конфиг для типовой базы на 50 активных пользователей:
# Память
shared_buffers = 8GB # ~25% RAM - стандартная отправная точка
work_mem = 64MB # на одну операцию сортировки/хэша; при 50 коннектах считай потолок
maintenance_work_mem = 512MB # для VACUUM, CREATE INDEX
effective_cache_size = 24GB # подсказка планировщику про OS page cache
# Контрольные точки
checkpoint_segments = 32 # буфер WAL между checkpoint; в 9.3 ещё старый параметр
checkpoint_completion_target = 0.9
# Запись
synchronous_commit = off # асинхронная фиксация - риск потери ~200мс транзакций при краше, но прирост заметный
wal_buffers = 16MB
# Соединения
max_connections = 100 # 1С сервер приложений делает пул сам; больше не нужно
# Планировщик
random_page_cost = 1.5 # SAS RAID, не SSD, но не 4.0 как для HDD
Несколько комментариев к этому:
work_mem = 64MB. Это значение умножается на количество одновременных операций, не на количество соединений. При 50 пользователях и сложных запросах 1С можно легко упереться в RAM. Если наблюдаете свопинг - режьте work_mem, не shared_buffers.synchronous_commit = off. Да, это снижает надёжность на окно ~200 мс. Для 1С в большинстве конфигураций это приемлемо - транзакции 1С сами по себе либо завершаются успешно по логике приложения, либо пользователь видит ошибку. Полная потеря данных при этом маловероятна - речь о самых последних транзакциях в момент краша. Клиент принял риск осознанно.checkpoint_segments = 32. В PostgreSQL 9.3 ещё старый параметр, в будущих версиях его планируют заменить наmax_wal_size. Пока работаем с тем что есть.
Что получилось
После недели работы с ~30 параллельными сессиями - стабильно. pg_stat_activity показывает нормальную картину, долгих блокировок нет. explain analyze на тяжёлых отчётах показывает планы, сравнимые с тем что было на MS SQL - в ряде мест даже чище, 1С генерирует запросы достаточно стандартные.
Где MS SQL выигрывал субъективно - это GUI-инструменты мониторинга и встроенный profiler. pg_stat_statements и pgBadger закрывают задачу, но требуют привыкания. Подключили мониторинг через Zabbix - настраивали связку с ELK для похожего клиента раньше, здесь пока только Zabbix.
Интеграция платформы 1С с нестандартной СУБД - это всегда больше работы, чем кажется из документации. Но в данном случае результат получился рабочий, и клиент доволен тем что избавился от лицензионной зависимости от Microsoft по этой части стека.