· 17 мин чтения

PostgreSQL с нуля: установка, настройка и честный тюнинг под корпоративную нагрузку

Я Семёнов Евгений Сергеевич, директор АйТи Фреш. За 15+ лет обслуживания корпоративных серверов у нас на практике прошли десятки развёртываний PostgreSQL — от базы 1С:ERP на производстве до 400 ГБ хранилища аналитики маркетплейса. И я видел, как одинаковый «ванильный» postgresql.conf загибается на сервере Dell с двумя Xeon Platinum 8280 и 256 ГБ памяти. База вроде поднялась, запросы идут — но вместо 2000 TPS даёт 120. В этой статье — пошаговый разбор, как установить PostgreSQL 16 на Linux, какие параметры менять и зачем, плюс реальные цифры из моих рабочих инсталляций.

Выбор версии и платформы

На момент написания актуальна PostgreSQL 16 с длительной поддержкой до ноября 2028 года. Я всегда беру последний стабильный мажор: в нём меньше багов, лучше планировщик, больше расширений. Если инфраструктура требовательна к совместимости с ПО (например, 1С требует ровно 15.x в официальной сборке), возьмите ближайший совместимый релиз.

По ОС — Ubuntu 22.04 LTS или RHEL 9 / Rocky Linux 9. Оба варианта проверены, оба работают. Windows — категорически не рекомендую даже под dev: производительность хуже на 20–30%, нет родных инструментов мониторинга, проблемы с блокировками файлов.

Установка из официального репозитория PGDG

Пакетная установка из апстримного репозитория PostgreSQL Global Development Group — единственный правильный путь. Дистрибутивный postgresql обычно отстаёт на минорный-мажорный релиз.

# Ubuntu 22.04
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
  --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
sudo sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \
  https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
  > /etc/apt/sources.list.d/pgdg.list'
sudo apt update
sudo apt install -y postgresql-16 postgresql-client-16 postgresql-contrib-16

После установки служба запустится автоматически, кластер будет в /var/lib/postgresql/16/main, конфиги — в /etc/postgresql/16/main/. Проверяем:

sudo systemctl status postgresql@16-main
sudo -u postgres psql -c "SELECT version();"

Правильная файловая структура и диски

На рабочих инсталляциях я никогда не оставляю базу в дефолтном пути на корневом диске. Стандартная схема:

Точка монтированияНазначениеРекомендуемый дискРазмер
/var/lib/postgresql/16/mainОсновная база (heap, индексы)NVMe RAID102–4x размер данных
/var/lib/postgresql/16/walWAL-логи (pg_wal)Отдельный NVMe или SSD100–200 ГБ
/backup/pgpg_basebackup, WAL-архивHDD RAID5/6 или NAS3x размер базы
/var/log/postgresqlТекстовые логиЛюбой SSD20–50 ГБ

Выделение WAL на отдельный диск даёт примерно 15–25% прироста на write-heavy нагрузках — я всегда так делаю, если сервер позволяет. Файловая система — XFS с опциями noatime,nodiratime, ext4 тоже нормально. Btrfs и ZFS — только если понимаете, зачем вам COW и сжатие (у нас один клиент на ZFS с lz4 получил экономию места 2,3x, но пришлось отключать full_page_writes в PostgreSQL).

Ключевые параметры postgresql.conf

Файл /etc/postgresql/16/main/postgresql.conf по умолчанию — для слабого ноутбука. Для продакшена его надо переписывать. Ниже — мой типовой шаблон для сервера с 64 ГБ RAM и NVMe:

# Подключения
listen_addresses = '*'
max_connections = 200
superuser_reserved_connections = 5

# Память
shared_buffers = 16GB                    # 25% от RAM
effective_cache_size = 48GB              # ~70% от RAM (подсказка планировщику)
work_mem = 32MB                          # на каждую сортировку/хэш
maintenance_work_mem = 2GB               # VACUUM, CREATE INDEX
wal_buffers = 64MB
huge_pages = try                         # включаем hugepages в ядре

# WAL и контрольные точки
wal_level = replica
max_wal_size = 8GB
min_wal_size = 2GB
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
wal_compression = on

# Параллелизм
max_worker_processes = 16
max_parallel_workers = 16
max_parallel_workers_per_gather = 4
max_parallel_maintenance_workers = 4

# Планировщик
random_page_cost = 1.1                   # для NVMe/SSD
effective_io_concurrency = 200           # NVMe
default_statistics_target = 200

# Логирование
log_destination = 'csvlog'
logging_collector = on
log_directory = '/var/log/postgresql'
log_min_duration_statement = 500         # запросы > 500 мс
log_checkpoints = on
log_lock_waits = on
log_temp_files = 10MB
log_autovacuum_min_duration = 1000

# Расширения
shared_preload_libraries = 'pg_stat_statements,auto_explain'

После правки конфига — перезагрузка: sudo systemctl restart postgresql@16-main. Параметры с пометкой «reload» можно подгружать без рестарта через SELECT pg_reload_conf();.

pg_hba.conf и безопасность

Файл pg_hba.conf управляет аутентификацией. По умолчанию PostgreSQL доверяет локальным подключениям по методу peer, всем остальным — отказывает. Для корпоративной базы минимум:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             postgres                                peer
local   all             all                                     scram-sha-256
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
host    appdb           appuser         10.10.0.0/16            scram-sha-256
host    replication     replicator      10.10.0.0/16            scram-sha-256
# Остальное явно запрещено — default deny

Пароли — только scram-sha-256, MD5 уже давно считается слабым. В конфиге password_encryption = scram-sha-256. При создании пользователя:

CREATE ROLE appuser LOGIN PASSWORD 'СтойкийПароль123!' VALID UNTIL '2027-01-01';
CREATE DATABASE appdb OWNER appuser ENCODING 'UTF8' LC_COLLATE 'ru_RU.UTF-8' LC_CTYPE 'ru_RU.UTF-8';

Мониторинг через pg_stat_statements и Prometheus

Без pg_stat_statements вы слепой. Это расширение ведёт накопленную статистику по всем запросам: количество вызовов, общее время, среднее время, чтения с диска, попадания в кэш. Включается в shared_preload_libraries + CREATE EXTENSION pg_stat_statements;. Топ-10 медленных запросов:

SELECT substring(query, 1, 80) AS query,
       calls, total_exec_time::int AS total_ms,
       mean_exec_time::int AS avg_ms, rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC LIMIT 10;

Для графиков — Prometheus postgres_exporter + Grafana dashboard 9628. Собирает 200+ метрик: транзакции, блокировки, bloat, репликация. У нас на практике один клиент (интернет-магазин на 1С-Битрикс, база 180 ГБ) благодаря этим графикам нашёл запрос, который раз в 10 минут сканил всю таблицу orders. После добавления индекса load average на сервере упал с 18 до 3.

Мини-кейс: база 1С:ERP на 120 пользователей

В феврале 2026 взяли в обслуживание производственный холдинг — 120 пользователей 1С:ERP, база 340 ГБ, старый HP ProLiant DL380 Gen9 с 128 ГБ RAM и HDD RAID10. Жалобы: закрытие месяца идёт 14 часов, ERP «висит» каждый день около 11 утра. Что сделали:

Результат: закрытие месяца за 2 часа 20 минут (было 14), средний отклик интерфейса 1С упал с 1,8 до 0,3 секунды, «зависаний» больше нет. Стоимость проекта — 280 тыс. руб. за работы плюс новое железо.

Бэкап, репликация и обслуживание

Правило: если у вас нет резервной копии за сегодня — у вас нет резервной копии вообще. Минимальный стек:

# archive_command в postgresql.conf
archive_mode = on
archive_command = 'test ! -f /backup/wal/%f && cp %p /backup/wal/%f'
wal_keep_size = 16GB

# Запуск базовой копии
sudo -u postgres pg_basebackup -D /backup/base/$(date +%Y%m%d) \
  -Ft -z -P -R -X stream

Обязательно раз в квартал тестируйте восстановление из бэкапа на отдельной машине. База, которую невозможно поднять — не база.

Настроим PostgreSQL под вашу нагрузку

Подниму PostgreSQL 16 на вашем сервере, настрою репликацию, бэкапы и мониторинг. Аудит текущего инстанса с рекомендациями по тюнингу — за один день, полная миграция с MS SQL или Oracle — от двух недель. Базы от 20 ГБ до нескольких ТБ.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — частые вопросы по PostgreSQL

Сколько памяти выделять под shared_buffers?
Стандартная рекомендация — 25% от RAM сервера. На машине с 64 ГБ ставим 16 ГБ, остальное оставляем под дисковый кэш ОС. Больше 40% не имеет смысла — PostgreSQL использует двойное кэширование через page cache Linux.
Какой work_mem выставить?
work_mem задаётся на каждую операцию сортировки/хэша. Для OLTP начните с 16–32 МБ, для аналитики можно 128–256 МБ. Если max_connections=200 и work_mem=64MB, в пике получите до 12,8 ГБ RAM на одни только сортировки.
Нужно ли отключать autovacuum?
Никогда. Отключённый autovacuum за месяц превращает базу в распухший неработоспособный файл. Тюньте параметры — autovacuum_vacuum_scale_factor, autovacuum_naptime — но не отключайте.
Какую файловую систему выбрать для PostgreSQL?
XFS или ext4 с опцией noatime. ZFS даёт сжатие и снапшоты, но требует аккуратной настройки recordsize=8K и отключения двойного кэширования. На продакшене под большие нагрузки я выбираю XFS на NVMe.
Как замерить реальную нагрузку на PostgreSQL?
Включите pg_stat_statements, настройте Prometheus postgres_exporter + Grafana dashboard. Смотрите top-10 запросов по total_time, метрики blks_hit/blks_read, размер базы и длину очереди на бэкенд.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.