PostgreSQL под 1С на терабайтах: что настроить заранее, чтобы не тушить пожар
Что меняется при росте
На объёме «как обычная MS SQL-база до 100 ГБ» PostgreSQL ведёт себя прозрачно: настройка по умолчанию работает, vacuum успевает за рабочий день, бэкап делается ночью. Проблемы стартуют, когда таблицы движений и регистров переваливают за пару сотен миллионов строк, а суточный поток операций исчисляется десятками миллионов. На этом масштабе включаются три механизма, про которые в небольших базах можно было не вспоминать: autovacuum, bloat и checkpoint pressure.
Autovacuum: невидимая работа
В Postgres удалённые и обновлённые строки физически остаются на странице до тех пор, пока их не вычистит vacuum. На больших таблицах это значит: или autovacuum работает почти непрерывно, или он не успевает и таблица раздувается. Параметры по умолчанию (autovacuum_vacuum_scale_factor = 0.2) означают, что vacuum запустится, когда в таблице 20% мёртвых строк. При 200 миллионах строк это 40 миллионов мёртвых — и одна такая чистка может идти часами.
Что настраивать сразу, а не потом
| Параметр | Значение по умолчанию | Что ставить на больших базах | Зачем |
|---|---|---|---|
shared_buffers |
128 MB | 25% ОЗУ; для типовой связки «один сервер = Postgres + Linux» обычно не больше 16 GB | Кэш страниц Postgres. Меньше — частые чтения с диска, дольше тяжёлые отчёты. На выделенных серверах с huge pages и Postgres 14+ верхняя граница 16 GB не догма — проверяйте на нагрузочном тесте |
work_mem |
4 MB | 32–64 MB | Память на операцию сортировки/хэширования. Большие отчёты 1С без этого пишут на диск |
maintenance_work_mem |
64 MB | 1–2 GB | Память для autovacuum и индексов. На больших таблицах критично |
autovacuum_vacuum_scale_factor |
0.2 | 0.05 для крупных таблиц через ALTER TABLE |
Чаще, но меньшими порциями — vacuum успевает |
checkpoint_timeout |
5 min | 15–30 min | Реже сбрасывать буфера на диск — меньше IO-всплесков |
max_wal_size |
1 GB | 8–16 GB | Чтобы checkpoint не дергался каждые две минуты при активной записи |
Не копируйте эти значения вслепую. На сервере с 8 ГБ ОЗУ shared_buffers = 4 GB положит ваш Postgres быстрее, чем дефолт. Цифры в таблице рассчитаны на типовой сервер 1С с 32–64 ГБ ОЗУ и SSD. Меньше ресурсов — пропорционально уменьшайте; больше — увеличивайте, но проверяйте на тесте.
Bloat: тихий съедатель диска
Когда autovacuum не успевает, таблицы и индексы раздуваются: физически они занимают много, а полезных данных там — половина. Это и есть bloat. Симптомы: размер базы растёт быстрее, чем количество данных; запросы тормозят без видимой причины; диск кончается раньше, чем ждали.
Как смотреть bloat — два пути:
- Установить расширение
pgstattupleи регулярно опрашивать самые тяжёлые таблицы — расширение возвращает точные данные о свободном пространстве внутри страниц. - Раз в неделю снимать топ-30 таблиц по размеру (
pg_total_relation_size) и сравнивать с предыдущей неделей — резкий скачок без роста данных = bloat.
Лечится: VACUUM FULL на конкретную таблицу (требует эксклюзивной блокировки — на проде только в окно обслуживания) или pg_repack (умеет переупаковывать без длительной блокировки, но нужно ставить отдельно).
Что наблюдать каждый день
- Свободное место на диске WAL (
pg_wal/) — если оно растёт быстрее ожидаемого, репликация или архивирование застряли. - Топ-10 самых долгих запросов через
pg_stat_statements— обычно там сидит один-два «толстых» отчёта 1С, которые гонят 80% нагрузки. - Число активных и idle-сеансов в
pg_stat_activity— многоidle in transaction= клиент 1С не закрыл транзакцию, и autovacuum не сможет работать. - Размер базы и топ-30 таблиц — недельный график. Аномалии видны сразу.
- Время последнего успешного autovacuum по большим таблицам (
pg_stat_all_tables.last_autovacuum) — если на крупной таблице старше суток, надо разбираться.
Типичные ошибки
- «Postgres сам разберётся». На активной базе с типовой нагрузкой 1С:ERP/УТ (десятки миллионов операций в сутки) дефолтных настроек хватает на 3–9 месяцев, дальше autovacuum перестаёт успевать и начинаются проблемы с bloat. На тихих учётных базах деградация может не наступить годами — но рассчитывать на это рискованно.
- Гигантский
shared_buffers«чтобы всё в память влезало». При 50% ОЗУ начнётся свопинг и двойное кэширование с ОС. Оптимум — 25%, не больше 16 ГБ. - Отключили autovacuum, чтобы «он не мешал». Это путь к bloat'у на терабайты за месяц. Правильно — наоборот, настроить его агрессивнее на крупных таблицах.
- Бэкап через
pg_dumpна терабайтной базе как штатный. Логический бэкап остаётся осмысленным для миграций между мажорными версиями Postgres и выгрузки отдельных таблиц, но как основной механизм резервного копирования на 1 ТБ+ он не подходит — восстановление занимает дни. Штатный бэкап на этом масштабе — физический:pg_basebackup, WAL-G, pgBackRest. - Индексы «на всякий случай». Платформа 1С создаёт базовый набор индексов под свои запросы. Добавлять собственные индексы имеет смысл только после анализа конкретного плана выполнения (
pg_stat_statements+EXPLAIN) — иначе можно увеличить стоимость записи и сбить статистику без выигрыша в чтении. - Запустили
VACUUM FULLна проде в рабочее время. Эксклюзивная блокировка на час — пользователи получают «ожидание блокировки». Только в окно обслуживания. - Игнорировать
idle in transaction. Один долгий такой сеанс — и autovacuum перестаёт чистить таблицы, которые трогала эта транзакция (срабатывает «горизонт XID»). На активной базе этого достаточно, чтобы bloat пошёл лавиной.
Перейти в каталог решений →