База PostgreSQL 10 выросла до 5 ТБ за месяц опытной эксплуатации. Около 3 ТБ заняла одна таблица. Система обрабатывала 4 млн первичных документов в месяц, хотя проект рассчитывали на 10 ТБ данных за год.

Эти цифры приводит статья Infostart «Особенности разработки больших и высоконагруженных баз 1С + PostgreSQL». В ней работало до 1000 активных пользователей. Это не 30 000 одновременных сеансов и не доказательство такого предела для одной базы 1С:ERP.

Для настройки важнее другое: сколько сеансов одновременно выполняют операции, как быстро растут таблицы и что загружено во время задержки. Ни размер штата, ни число заведённых учётных записей этого не показывают.

Ниже — стартовый профиль для сервера с 128 ГБ RAM, 32 vCPU и NVMe RAID 10. Его нельзя копировать вслепую. Часть параметров пересчитывается по памяти, а autovacuum настраивается по накоплению старых версий строк.

Два кейса нельзя складывать в один

Первый кейс описывает реальную систему на PostgreSQL 10. В ней работало до 1000 активных пользователей, а поток первичных данных достигал 4 млн записей в месяц.

Второй материал — статья «Инженерный контур 1С. Часть 2», опубликованная Infolimp 5 сентября 2026 года. Автор прямо называет торговый контур обобщённым сценарием, а не отчётом о внедрении.

В этом сценарии база занимает 1,8 ТБ. PostgreSQL 16 работает на Linux, сервер получил 128 ГБ RAM, 32 vCPU и NVMe RAID 10. На пике автор закладывает 350 одновременно активных сеансов и свыше 40 000 транзакций маркировки в сутки.

КейсСУБД и нагрузкаНаблюдаемый симптомЧто можно перенести
Высоконагруженная база из статьи InfostartPostgreSQL 10, до 1000 активных пользователей, около 4 млн первичных данных в месяцБаза выросла до 5 ТБ за месяц, одна таблица заняла около 3 ТБПодход к настройке autovacuum при быстром росте таблиц
Обобщённый торговый контур InfolimpPostgreSQL 16, база 1,8 ТБ, пик 350 активных сеансовp95 проведения отгрузки достиг 14,2 секунды при цели менее 2,5 секундыПрофиль памяти для хоста со 128 ГБ RAM
Тот же торговый контурБолее 40 000 транзакций маркировки в суткиИнтерфейс и обработчики API зависают на 5–12 секундПорядок поиска ожиданий, тяжёлых запросов и проблем очистки

Вывод: цифры описывают разные системы. Их нельзя объединить в утверждение о работе одной базы с 30 000 одновременных пользователей.

Даже формулировка «1000 активных пользователей» требует осторожности. Она не сообщает, сколько людей одновременно проводили документы и сколько соединений выполняли запросы в конкретную секунду. Во втором кейсе этот показатель назван прямо — 350 сеансов на пике.

Поэтому начните не с общего числа пользователей. Зафиксируйте одновременные сеансы, поток операций, размер крупнейших таблиц и профиль нагрузки на CPU и диски. Для воспроизводимой проверки подойдёт нагрузочный сценарий для активных сеансов 1С.

Память считают от роли сервера

В обобщённом кейсе PostgreSQL стартовал с shared_buffers = 128MB, work_mem = 4MB и checkpoint_timeout = 5min. Такие значения не учитывают сервер со 128 ГБ памяти и нагрузку 1С:ERP.

Руководство Andko по настройке PostgreSQL для 1С предлагает отдавать СУБД до 70% физической памяти на выделенном сервере. Если платформа 1С работает на том же хосте, долю снижают до 50%.

Для выделенного сервера расчёт выглядит так:

128 ГБ × 0,70 = 89,6 ГБ

Это не значение одного параметра. Это верхняя рамка памяти для процессов PostgreSQL, кэшей и рабочих операций.

Для совмещённого хоста расчёт другой:

128 ГБ × 0,50 = 64 ГБ

Остаток нужен серверу 1С, операционной системе и сопутствующим службам. Переносить лимит 89,6 ГБ на совмещённый сервер нельзя.

Для shared_buffers руководство Andko предлагает 25% доступной RAM. На хосте из кейса расчёт даёт:

128 ГБ × 0,25 = 32 ГБ

Этот результат совпадает со значением из материала Infolimp. Значит, 32GB можно взять как старт для описанного хоста, но не как норму для любого сервера.

ПараметрИсходное значениеСтарт для хоста из кейсаОснованиеЧто проверить
shared_buffers128MB32GB25% от 128 ГБ по руководству Andko; то же значение у InfolimpХватает ли памяти ОС и другим процессам
effective_cache_sizeНе указано96GBЗначение из профиля Infolimp; оно равно 75% RAMНе считать его отдельным резервом памяти
work_mem4MB48MBПрофиль Infolimp для конкретного контураЧисло параллельных сортировок и соединений
temp_buffersНе указано16MBПрофиль InfolimpОбъём временных таблиц каждого сеанса
checkpoint_timeout5minНе переносить без замеровИсходное значение дано Infolimp, нового универсального значения нетЧастоту контрольных точек и запись WAL

Вывод: для 128 ГБ RAM обоснован старт с shared_buffers = 32GB. Остальные значения относятся к конкретному профилю и требуют проверки под рабочей нагрузкой.

effective_cache_size не резервирует 96 ГБ поверх shared_buffers. Параметр сообщает планировщику, какой объём данных может находиться в кэше PostgreSQL и операционной системы.

С work_mem риск обратный. PostgreSQL выделяет эту память не один раз на весь сервер, а для отдельных операций сортировки и хеширования. При множестве одновременных запросов значение 48MB способно дать расход, который нельзя оценивать простым сложением с shared_buffers.

Перед включением строгого режима Huge Pages сверьте расчёт резерва памяти Linux для PostgreSQL. Ошибка в vm.nr_hugepages может оставить СУБД без нужного объёма страниц при запуске.

Диск влияет на планировщик, но не отменяет диагностику

Для SSD руководство Andko предлагает random_page_cost от 1.1 до 1.5. Для NVMe там же указано effective_io_concurrency = 200; для SATA SSD — 100, для HDD — 2.

Эти значения описывают тип накопителя, а не скорость конкретного массива. Контроллер, RAID, прошивка, очередь запросов и фоновые операции меняют фактическое поведение дисковой подсистемы.

На NVMe RAID 10 из обобщённого кейса можно начать с такого фрагмента:

random_page_cost = 1.1
effective_io_concurrency = 200

Верхняя граница random_page_cost = 1.5 пригодится для повторной проверки плана. Если план запросов не меняется, подбор десятых долей не устранит задержку сам по себе.

Не снижайте стоимость случайного чтения только потому, что в сервере стоит NVMe. Сначала сравните планы тяжёлых запросов и ожидания. Иначе настройка заставит планировщик чаще выбирать случайный доступ, хотя причина задержки лежит в блокировках или нехватке статистики.

Autovacuum настраивают по росту старых версий строк

PostgreSQL не удаляет изменённую строку сразу. Старая версия остаётся в таблице до очистки autovacuum. При большом потоке изменений такие версии увеличивают таблицы и объём работы для чтения.

В сценарии Infolimp доля неактуальных версий достигала 28–35% таблиц. В кейсе Infostart одна таблица выросла примерно до 3 ТБ, а всю базу пришлось удерживать от дальнейшего разрастания более агрессивной очисткой.

Авторы первого кейса снизили autovacuum_vacuum_scale_factor с 0.2 до 0.01. Они также подняли autovacuum_vacuum_cost_limit до 1000 и оставили autovacuum_vacuum_cost_delay = 20ms.

Это параметры тяжёлого случая. Значение 0.01 нельзя объявить общей нормой для 1С:ERP.

Руководство Andko предлагает более осторожную стартовую точку: четыре рабочих процесса autovacuum, интервал запуска 30 секунд, порог очистки 0.05 и порог анализа 0.02.

ПараметрОсторожный стартЗначение из тяжёлого кейсаКогда менять
autovacuum_max_workers4Не указаноРабочие процессы не успевают обходить крупные таблицы
autovacuum_naptime30sНе указаноОчистка запускается реже, чем растёт объём изменений
autovacuum_vacuum_scale_factor0.050.01При работающем autovacuum снова растёт доля старых версий
autovacuum_analyze_scale_factor0.02Не указаноПланы строятся по устаревшей статистике
autovacuum_vacuum_cost_limitПроверить под диском1000Очистка отстаёт, а диск сохраняет запас по нагрузке
autovacuum_vacuum_cost_delayПроверить под диском20msМенять вместе с лимитом, а не отдельно

Вывод: начните с autovacuum_vacuum_scale_factor = 0.05. Переход к 0.01 оправдан, если старые версии снова накапливаются при работающей очистке.

У порога есть неприятная особенность: он зависит от размера таблицы. Чем крупнее таблица, тем больше изменений потребуется до запуска очистки по доле строк. Поэтому один общий профиль может справляться с небольшими таблицами и опаздывать на крупнейшей.

Следите не только за фактом запуска autovacuum. Нужны скорость накопления старых версий, длительность очистки и конкуренция за диск. Если очистка постоянно работает, но отставание растёт, дальнейшее сокращение интервала лишь добавит фоновой нагрузки.

PgBouncer распределяет соединения, но не создаёт ресурсы

Репозиторий aidarsafindev/1c-pgbouncer-arbiter показывает приоритизацию запросов через три экземпляра PgBouncer. Пулы HIGH, NORMAL и LOW получают разные лимиты соединений, а TCP-арбитр на Python выбирает пул по application_name.

Демонстрация хорошо показывает границу метода. Клиент psql передаёт application_name, а 1С не делает этого тем же способом. Для 1С также нужен pool_mode = session.

В этом режиме отмена запроса через pg_cancel_backend не освобождает соединение. Репозиторий ограничивает вытеснение read-only-запросами из пула LOW; пишущие INSERT, UPDATE и DELETE не отменяются.

ОграничениеЧто происходитПрактический вывод
1С не передаёт ожидаемый application_nameАрбитр не получает готовый признак приоритетаНужен собственный способ классификации
1С требует pool_mode = sessionСоединение закреплено за сеансомОтмена запроса не возвращает слот в пул
CPU или диск загружены на 100%Все пулы конкурируют за исчерпанный ресурсПриоритизация не устраняет дефицит
Таблицы общие для трёх пуловБлокировки действуют на всехОтдельный пул не изолирует данные
Пишущие запросы не вытесняютсяДолгая запись продолжает занимать ресурсLOW-пул не гарантирует освобождение сервера

Вывод: PgBouncer управляет доступом к соединениям, но не лечит перегруженный CPU, диск и общие блокировки.

Если запросы образуют очередь внутри базы, сначала определите место ожидания. Граница между настройкой PostgreSQL и выносом очереди зависит от захвата строк, индексов и требований к повторной обработке.

Стартовый профиль для сервера из кейса

Для выделенного хоста с 128 ГБ RAM, 32 vCPU, PostgreSQL 16 и NVMe RAID 10 стартовый фрагмент выглядит так:

shared_buffers = 32GB
effective_cache_size = 96GB
work_mem = 48MB
temp_buffers = 16MB

random_page_cost = 1.1
effective_io_concurrency = 200

autovacuum_max_workers = 4
autovacuum_naptime = 30s
autovacuum_vacuum_scale_factor = 0.05
autovacuum_analyze_scale_factor = 0.02

Это исходная точка, а не готовый конфигурационный файл. Профиль собран для базы 1,8 ТБ и пика в 350 активных сеансов. Он не подтверждает работу 30 000 одновременных пользователей.

При другом объёме RAM пересчитайте долю памяти PostgreSQL и shared_buffers. Для выделенного сервера используйте рамку до 70%, для совмещённого — до 50%, а shared_buffers начните с 25% памяти.

work_mem, temp_buffers, параметры autovacuum и ввода-вывода линейно не масштабируйте. Проверьте их повторным прогоном одинакового сценария. Для одной тяжёлой операции используйте проверку запросов PostgreSQL при медленном закрытии месяца.

После изменения сравните четыре признака:

  1. p95 выбранной операции приблизился к вашему нормативу.
  2. Старые версии строк не накапливаются между циклами autovacuum.
  3. Пиковый расход памяти не уводит сервер в swap и OOM.
  4. CPU и диск сохраняют запас при том же числе активных сеансов.

Если результат зависит от структуры таблиц, числа параллельных операций и профиля запросов, готовая статья не заменит обследование. После контрольного прогона можно заказать технический разбор настроек PostgreSQL под конкретную базу.

Главное правило простое: переносите из чужого кейса метод проверки и стартовые значения под совпадающие исходные данные. Чужое число пользователей переносить нельзя.

1с:erp autovacuum postgres pro postgresql настройка памяти