Представь, что твой PostgreSQL работает медленно, запросы "висят", а сервер постоянно упирается в память. Проблема часто не в коде приложения, а в неправильно рассчитанных настройках сервера. Давай разберем, как правильно рассчитать основные параметры PostgreSQL для твоей конкретной инфраструктуры и нагрузки.
Основные принципы расчета настроек PostgreSQL
Перед тем как погружаться в формулы, запомни три важных правила:
- Никаких "магических чисел" — все настройки зависят от твоих ресурсов и нагрузки
- Постепенная настройка — меняй параметры по одному и тестируй
- Мониторинг обязателен — без метрик ты летишь вслепую
Шаг 1: Расчет параметров памяти
shared_buffers — кэш PostgreSQL
Это самый важный параметр. Он определяет, сколько оперативной памяти PostgreSQL использует для кэширования данных.
Формула расчета:
shared_buffers = 25% от доступной RAM, но не более 8 ГБ
Для системы с 16 ГБ RAM:
# postgresql.conf
shared_buffers = 4GB # 25% от 16GB = 4GB
# sysctl -w kernel.shmmax=4294967296 # 4GB в байтах
work_mem — память на операцию сортировки
Определяет, сколько памяти выделяется каждой операции сортировки или хеширования в рамках одного запроса.
Формула расчета:
work_mem = (общая RAM - shared_buffers) / (max_connections * 2)
Пример для 16 ГБ RAM и 100 подключений:
# (16384MB - 4096MB) / (100 * 2) = 12288 / 200 ≈ 61MB
work_mem = 64MB
maintenance_work_mem — память для служебных операций
Используется для VACUUM, CREATE INDEX, ALTER TABLE и других операций обслуживания.
Формула расчета:
maintenance_work_mem = 5% от общей RAM, но не более 2 ГБ
# 5% от 16GB = 0.8GB = 819MB
maintenance_work_mem = 819MB
Шаг 2: Расчет параметров подключений
max_connections — максимальное число подключений
Критически важный параметр. Каждое подключение потребляет ресурсы, особенно память.
| Тип приложения | Рекомендуемое значение | Обоснование |
|---|---|---|
| Веб-приложение (OLTP) | 100-200 | Используй пул соединений в приложении |
| Аналитика (OLAP) | 20-50 | Длительные запросы, меньше параллелизма |
| Микросервисы | 50-100 на сервис | Учитывай общее количество сервисов |
# Для типичного веб-приложения
max_connections = 100
# Всегда настройте пул соединений!
# В application.properties (Spring Boot):
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
Шаг 3: Дисковые настройки и Write-Ahead Log
checkpoint_segments → max_wal_size
В PostgreSQL 9.5+ используй max_wal_size вместо checkpoint_segments. Контролирует частоту контрольных точек.
Формула расчета:
max_wal_size = 1GB на каждые 1GB shared_buffers
# Для shared_buffers = 4GB
max_wal_size = 4GB
checkpoint_completion_target = 0.9 # 90% заполнения между контрольными точками
effective_cache_size — оценка кэша ОС
Не выделяет память, а помогает планировщику выбирать оптимальные планы запросов.
Формула расчета:
effective_cache_size = 50-75% от общей RAM
# Для 16GB RAM
effective_cache_size = 12GB # 75% от 16GB
Шаг 4: Готовые конфигурации для разных сценариев
Конфигурация для веб-приложения (16 ГБ RAM)
# postgresql.conf - Web Application Preset
shared_buffers = 4GB
work_mem = 64MB
maintenance_work_mem = 819MB
effective_cache_size = 12GB
max_connections = 100
max_wal_size = 4GB
checkpoint_completion_target = 0.9
wal_buffers = 16MB # Автонастройка обычно работает, но можно явно указать
# Оптимизация для SSD
random_page_cost = 1.1 # Для SSD вместо 4.0
effective_io_concurrency = 200 # Для NVMe SSD
Конфигурация для аналитической нагрузки (64 ГБ RAM)
# postgresql.conf - OLAP/Analytics Preset
shared_buffers = 8GB # Максимум 8GB даже при 64GB RAM
work_mem = 256MB # Большие сортировки и агрегации
maintenance_work_mem = 2GB # Максимум для VACUUM и индексов
effective_cache_size = 48GB
max_connections = 30 # Меньше подключений, но больше памяти на каждое
max_wal_size = 8GB
wal_buffers = 16MB
# Для сложных аналитических запросов
enable_hashagg = on
enable_hashjoin = on
enable_material = on
Шаг 5: Проверка и мониторинг настроек
После применения настроек обязательно проверь их работу:
-- Проверка текущих настроек
SELECT name, setting, unit, context
FROM pg_settings
WHERE name IN (
'shared_buffers',
'work_mem',
'max_connections',
'effective_cache_size'
);
-- Мониторинг использования памяти
SELECT
name,
setting,
(setting::bigint * 8192) / 1024 / 1024 as size_mb
FROM pg_settings
WHERE name LIKE '%buffers%' OR name LIKE '%mem%';
-- Проверка контрольных точек
SELECT
checkpoints_timed,
checkpoints_req,
checkpoint_write_time,
checkpoint_sync_time
FROM pg_stat_bgwriter;
Часто задаваемые вопросы (FAQ)
Как часто нужно пересчитывать настройки PostgreSQL?
Пересматривай настройки при: 1) Изменении объема RAM на сервере, 2) Увеличении нагрузки в 2+ раза, 3) Смене типа дисков (HDD → SSD), 4) Изменении паттернов запросов. Регулярно мониторь pg_stat_statements.
Почему shared_buffers не должен превышать 8 ГБ?
Из-за двойного кэширования: Linux уже кэширует файлы в page cache. При shared_buffers > 8GB возникает избыточное кэширование и конкуренция за память. Исключение — очень большие БД (> 1TB), где важен предсказуемый кэш.
Что делать, если не хватает памяти после настройки?
1) Уменьши max_connections, 2) Используй пул соединений в приложении, 3) Увеличь swap (временное решение), 4) Добавь RAM. Помни формулу: Общая память ≥ shared_buffers + (max_connections × work_mem) + maintenance_work_mem + запас (2-3GB).
Как рассчитать настройки для контейнеризованного PostgreSQL?
Используй memory limits контейнера вместо общей RAM сервера. Установи cgroup memory limit и рассчитывай параметры от него. Уменьши shared_buffers до 15-20% от лимита контейнера, так как в контейнерах меньше ресурсов.
Заключение
Расчет настроек PostgreSQL — это не разовая задача, а итеративный процесс. Начни с формул из этой статьи, примени их к своему серверу, затем мониторь производительность и корректируй параметры. Помни, что идеальных настроек "на все случаи" не существует — лучшая конфигурация та, которая оптимальна для твоей конкретной нагрузки и железа.