Настройка под нагрузку и под 1С

Рейтинг: 71.7% · 16 голосов
Подробный курс по PostgreSQL: SQL по демобазе, типы данных и JSONB, индексы, транзакции и MVCC, VACUUM, EXPLAIN и планировщик, роли и привилегии, репликация, бэкап, настройка под нагрузку и под 1С. Актуально на 2026.
Ответить
Аватара пользователя
Egor_DBA
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Настройка под нагрузку и под 1С

Сообщение Egor_DBA »

Оглавление курса (47)
  1. Что такое PostgreSQL: история, философия, где применяется
  2. Урок 1. Что нового в PostgreSQL 15 и далее (15 -> 16 -> 17)
  3. Установка и первый запуск: Linux, Windows, Docker
  4. psql детально: метакоманды и работа в консоли
  5. Демобаза Авиаперевозки Postgres Pro: структура и развёртывание
  6. SELECT: проекция, фильтрация, сортировка
  7. Транзакции и ACID
  8. Уровни изоляции транзакций: Read Committed, Repeatable Read, Serializable
  9. Соединения таблиц (JOIN)
  10. Агрегация: GROUP BY, HAVING, GROUPING SETS
  11. Подзапросы и CTE (WITH), рекурсия
  12. Оконные функции
  13. Изменение данных: INSERT/UPDATE/DELETE, UPSERT, MERGE
  14. Числовые и булевы типы, NULL и трёхзначная логика
  15. Строки, текст, дата и время, таймзоны
  16. Массивы, диапазоны, enum, составные типы
  17. JSON и JSONB: операторы и индексация
  18. DDL: CREATE TABLE, схемы, ALTER
  19. Ограничения целостности
  20. Представления и материализованные представления
  21. Последовательности, IDENTITY, генерируемые столбцы
  22. Индексы: B-tree и когда индекс не используется
  23. Типы индексов: Hash, GiST, SP-GiST, GIN, BRIN
  24. Продвинутые индексы: частичные, по выражению, покрывающие
  25. Обслуживание индексов и таблиц: bloat, REINDEX, CONCURRENTLY
  26. Полнотекстовый поиск
  27. Роли и пользователи
  28. Привилегии: GRANT/REVOKE
  29. Row-Level Security и безопасность данных
  30. Подключение приложения: pg_hba.conf, SSL, пулы соединений
  31. Серверное программирование: функции и процедуры
  32. Триггеры и события
  33. Архитектура PostgreSQL: процессы и память
  34. MVCC: версии строк и видимость
  35. VACUUM, autovacuum, freeze и wraparound
  36. WAL, контрольные точки и долговечность
  37. Блокировки и взаимоблокировки
  38. Планировщик запросов
  39. EXPLAIN и EXPLAIN ANALYZE: чтение планов
  40. Конфигурация сервера: ключевые параметры
  41. Настройка под нагрузку и под 1С (вы здесь)
  42. Параллельные запросы и партиционирование
  43. Резервное копирование и восстановление
  44. Репликация: потоковая и hot standby
  45. Логическая репликация и кластерные решения
  46. Внешние данные, расширения и сертификация
  47. Разбор планов запросов на explain.tensor.ru: глубокое чтение EXPLAIN ANALYZE
Урок 40. Настройка под нагрузку и под 1С

В прошлых уроках мы разобрали отдельные параметры конфигурации, планировщик и чтение планов через explain analyze. Теперь соберём это в инженерную задачу: как настроить postgresql под конкретный профиль работы. Профилей два разных, и тянуть их одной конфигурацией нельзя. Первый - OLTP: много коротких транзакций, тысячи мелких чтений и записей в секунду (касса, склад, веб-бэкенд). Второй - отчётность и аналитика: редкие, но тяжёлые запросы, которые молотят миллионы строк. Отдельным большим блоком идёт специфика РФ - postgresql для 1с, потому что 1С ведёт себя на сервере БД не как обычное приложение, и без правильной сборки и параметров работает медленно или криво.

Изображение

Как это работает

OLTP и отчётность нагружают сервер по-разному, и оптимизации у них конфликтуют. OLTP упирается в задержку одной транзакции и в конкуренцию за блокировки и за WAL. Здесь важно, чтобы рабочий набор данных лежал в памяти (shared_buffers и кэш ОС), чтобы коммиты не ждали диск дольше нужного, и чтобы autovacuum успевал чистить мёртвые версии строк (MVCC из урока 34), иначе таблицы пухнут и всё проседает.

Отчётность упирается в пропускную способность одного запроса. Ей нужно много памяти на сортировку и хэши (work_mem), агрессивный параллелизм и крупные порции чтения с диска. Если на одном сервере живут оба профиля, их разводят: глобально ставят консервативные значения, а тяжёлым отчётам поднимают work_mem и параллелизм локально - через SET внутри сессии или per-role настройкой, чтобы один отчёт не выжрал память у сотни кассиров.

Ключевая развилка по памяти простая. shared_buffers - это общий буферный кэш страниц, обычно 25 процентов ОЗУ как старт. work_mem - это лимит на ОДНУ операцию сортировки или хэша в ОДНОМ запросе, и запрос может взять несколько таких кусков сразу, а параллельные воркеры - ещё по копии. Поэтому work_mem умножается на реальную конкуренцию, и завышенное значение при сотнях соединений уводит сервер в OOM. Отсюда правило: высокий work_mem - не глобально, а точечно отчётам.

Теперь про 1С. Она проектировалась под СУБД, где временные таблицы создаются и наполняются на лету десятками за запрос. PostgreSQL по умолчанию не собирает статистику по таблице сразу после наполнения - он ждёт autovacuum. Для обычного приложения это норма, а для 1С смертельно: планировщик видит свежую временную таблицу без статистики, считает её крошечной и строит ужасный план (вложенные циклы вместо хэша). Лечит это расширение online_analyze - оно запускает ANALYZE немедленно после INSERT/UPDATE в таблицу, и планировщик сразу получает реальные оценки. Второе расширение, plantuner, с опцией fix_empty_table заставляет считать пустую таблицу действительно пустой, а не как одну строку - это убирает ещё один класс кривых планов. Оба расширения входят в сборки Postgres Pro и в сборку PostgreSQL для 1С от 1С, поэтому под 1С берут именно такой дистрибутив, а не ванильный.

SQL и примеры

Базовый OLTP-набор в postgresql.conf (значения - старт под сервер, скажем, 64 ГБ ОЗУ, крутить по факту):

Код: Выделить всё

shared_buffers = 16GB            # ~25% ОЗУ
effective_cache_size = 48GB      # подсказка планировщику: память под кэш всего
work_mem = 32MB                  # на ОДНУ сортировку/хэш; осторожно при многих коннектах
maintenance_work_mem = 2GB       # для VACUUM, CREATE INDEX, REINDEX
max_connections = 100            # держим низким, остальное - через пул
wal_compression = on
checkpoint_completion_target = 0.9
max_wal_size = 16GB              # реже контрольные точки = ровнее запись
random_page_cost = 1.1           # для SSD/NVMe, по умолчанию 4 - это про HDD
Профиль отчётности отличается параллелизмом и памятью под запрос. Глобально - умеренно, тяжёлому отчёту - локально:

Код: Выделить всё

-- глобально в конфиге
max_parallel_workers_per_gather = 4
max_parallel_workers = 8

-- а внутри сессии конкретного отчёта поднимаем точечно
SET work_mem = '1GB';
SET max_parallel_workers_per_gather = 8;
-- тяжёлый отчёт по демобазе bookings: выручка по месяцам
SELECT date_trunc('month', f.scheduled_departure) AS m,
       sum(tf.amount) AS revenue
FROM   bookings.ticket_flights tf
JOIN   bookings.flights f ON f.flight_id = tf.flight_id
GROUP  BY 1
ORDER  BY 1;
RESET work_mem;
Проверяем, что отчёту реально хватило памяти, через explain analyze - в плане не должно быть Sort Method external merge Disk:

Код: Выделить всё

EXPLAIN (ANALYZE, BUFFERS)
SELECT a.city, count(*)
FROM   bookings.ticket_flights tf
JOIN   bookings.flights f      ON f.flight_id = tf.flight_id
JOIN   bookings.airports a     ON a.airport_code = f.departure_airport
GROUP  BY a.city
ORDER  BY count(*) DESC;
Минимальный стартовый блок параметров под 1С (помимо самой сборки с online_analyze и plantuner):

Код: Выделить всё

# обязательно для корректной работы 1С
online_analyze.enable = on
online_analyze.table_type = 'temporary'   # анализировать временные таблицы
online_analyze.local_tracking = on
online_analyze.min_interval = 10000
plantuner.fix_empty_table = on

standard_conforming_strings = off          # совместимость со строками 1С
escape_string_warning = off
max_locks_per_transaction = 256            # 1С плодит много объектов на транзакцию
Включить расширения в нужной базе (один раз):

Код: Выделить всё

CREATE EXTENSION IF NOT EXISTS online_analyze;
CREATE EXTENSION IF NOT EXISTS plantuner;
SHOW shared_preload_libraries;             -- оба должны быть в списке
Частые грабли
  • work_mem задрали глобально (например 1GB) при max_connections под тысячу - и сервер ловит OOM, потому что память умножается на число параллельных сортировок, а не выдаётся один раз.
  • Отключили fsync ради скорости на тесте и забыли вернуть на проде. fsync = off означает: при сбое питания база может стать нечитаемой целиком. Скорость есть, данных нет.
  • Поставили max_connections = 2000 вместо пула. Каждое соединение - это процесс и память; правильно держать max_connections низким и ставить пул (PgBouncer, для 1С обычно transaction-режим не подходит из-за временных таблиц - берут session-режим).
  • Под 1С взяли ванильный PostgreSQL без online_analyze - и удивляются тормозам отчётов. Без немедленного ANALYZE временных таблиц 1С работает на кривых планах.
  • Скопировали чужой postgresql.conf целиком. Конфиг привязан к железу и профилю нагрузки; чужие 64 ГБ shared_buffers на вашем сервере с 16 ГБ ОЗУ положат старт.
  • Забыли про autovacuum под OLTP: при высокой записи дефолтных порогов мало, таблицы пухнут (bloat), и быстрый сервер за неделю превращается в медленный.
  • random_page_cost = 4 на NVMe - планировщик избегает индексов там, где они выгодны. Для SSD ставьте около 1.1.
Мини-лаба
  • Посмотрите текущие значения: SHOW shared_buffers; SHOW work_mem; SHOW max_connections; SHOW random_page_cost; запишите их.
  • На демобазе bookings выполните тяжёлый отчёт (выручка по месяцам выше) с EXPLAIN (ANALYZE, BUFFERS) при дефолтном work_mem и найдите в плане строку Sort Method - external merge Disk означает нехватку памяти.
  • Сделайте SET work_mem = '256MB'; повторите тот же EXPLAIN ANALYZE и сравните: ушёл ли Disk, упало ли общее время.
  • Создайте временную таблицу CREATE TEMP TABLE t AS SELECT * FROM bookings.ticket_flights LIMIT 200000; и сразу выполните EXPLAIN на JOIN с ней БЕЗ ручного ANALYZE - оцените, как планировщик угадал число строк.
  • Выполните ANALYZE t; повторите EXPLAIN и сравните оценки строк до и после - это ровно то, что online_analyze делает автоматически под 1С.
  • Через RESET work_mem; верните значение и убедитесь через SHOW, что вернулось.
Контрольные вопросы
  • Чем отличаются shared_buffers и work_mem по смыслу и по тому, на что умножается каждый из них при нагрузке?
  • Почему высокий work_mem опасно ставить глобально и как правильно дать память тяжёлому отчёту?
  • Какую проблему планировщика решает расширение online_analyze и почему она критична именно для 1С?
  • Что делает plantuner.fix_empty_table и какой класс кривых планов это убирает?
  • Чем грозит fsync = off на продакшене и зачем его вообще иногда выключают?
  • Почему под высокую нагрузку держат низкий max_connections и ставят пул соединений вместо тысяч прямых коннектов?
👍2 ❤️2 🔥 😄 🤔
Аватара пользователя
martinj63
Сообщения: 1
Зарегистрирован: 17 май 2026, 06:07

Re: Настройка под нагрузку и под 1С

Сообщение martinj63 »

А если на одном сервере и касса 1С, и ночные отчёты бухгалтерии - online_analyze отчётам не мешает лишними ANALYZE? Или его можно только на temp оставить?
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
jim234
Сообщения: 1
Зарегистрирован: 28 май 2026, 17:21

Re: Настройка под нагрузку и под 1С

Сообщение jim234 »

Поставил work_mem 512MB глобально, наутро прод лёг по памяти. Теперь дошло почему. Раскидал через ALTER ROLE reporting SET work_mem, кассирам оставил 32MB, полет нормальный.
👍 ❤️1 🔥 😄 🤔2
Ответить
← Предыдущая глава
Конфигурация сервера: ключевые параметры
Следующая глава →
Параллельные запросы и партиционирование

Все главы курса «PostgreSQL: от первого запроса до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «PostgreSQL: от первого запроса до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя