На главную

DevOps и серверы

Тюнинг PostgreSQL

По объёму памяти, числу ядер и типу нагрузки считает shared_buffers, work_mem и остальные параметры postgresql.conf — с объяснением, что каждый из них делает.

Железо и нагрузка

По умолчанию для этой нагрузки — 200

Много коротких запросов, данные помещаются в память.

Параметры

ПараметрЗначение
max_connections200
shared_buffers4GB
effective_cache_size12GB
maintenance_work_mem1GB
work_mem10MB
checkpoint_completion_target0.9
wal_buffers16MB
default_statistics_target100
random_page_cost1.1
effective_io_concurrency200
min_wal_size1GB
max_wal_size4GB
max_worker_processes4
max_parallel_workers_per_gather2
max_parallel_workers4
max_parallel_maintenance_workers2
huge_pagesoff

Оговорки

  • Это отправная точка, а не истина: после применения смотрите pg_stat_statements и долгие запросы, иначе тюнинг превращается в гадание.

ALTER SYSTEM

ALTER SYSTEM SET max_connections = '200';
ALTER SYSTEM SET shared_buffers = '4GB';
ALTER SYSTEM SET effective_cache_size = '12GB';
ALTER SYSTEM SET maintenance_work_mem = '1GB';
ALTER SYSTEM SET work_mem = '10MB';
ALTER SYSTEM SET checkpoint_completion_target = '0.9';
ALTER SYSTEM SET wal_buffers = '16MB';
ALTER SYSTEM SET default_statistics_target = '100';
ALTER SYSTEM SET random_page_cost = '1.1';
ALTER SYSTEM SET effective_io_concurrency = '200';
ALTER SYSTEM SET min_wal_size = '1GB';
ALTER SYSTEM SET max_wal_size = '4GB';
ALTER SYSTEM SET max_worker_processes = '4';
ALTER SYSTEM SET max_parallel_workers_per_gather = '2';
ALTER SYSTEM SET max_parallel_workers = '4';
ALTER SYSTEM SET max_parallel_maintenance_workers = '2';
ALTER SYSTEM SET huge_pages = 'off';
SELECT pg_reload_conf();
-- shared_buffers, max_connections и huge_pages требуют перезапуска сервера.

Что означает каждый параметр

max_connections = 200

Столько одновременных соединений держит база. Каждое — отдельный процесс, поэтому больше нескольких сотен обычно берут пулером (PgBouncer), а не этим числом.

shared_buffers = 4GB

Собственный кэш страниц PostgreSQL — четверть памяти машины. Остальное оставляем кэшу файловой системы: он тоже держит эти страницы.

effective_cache_size = 12GB

Не выделяет память, а подсказывает планировщику, сколько данных вероятно окажется в кэше. От этого зависит, выберет ли он индекс.

maintenance_work_mem = 1GB

Память под VACUUM, CREATE INDEX и ALTER TABLE. Больше — быстрее перестройка индексов.

work_mem = 10MB

Память на одну операцию сортировки или хеша. Множится на число операций и соединений — отсюда деление на 200 × 3.

checkpoint_completion_target = 0.9

Растягивает запись контрольной точки почти на весь интервал: диск не получает всплеск в конце.

wal_buffers = 16MB

Буфер журнала предзаписи. 16 МБ — размер одного сегмента WAL, больше не нужно.

default_statistics_target = 100

Подробность статистики по столбцам. Для аналитики выше: планировщику важнее точная оценка числа строк.

random_page_cost = 1.1

Стоимость случайного чтения относительно последовательного. Для SSD / NVMe разница почти исчезла, и значение 4 из времён HDD заставляет планировщик избегать индексов.

effective_io_concurrency = 200

Сколько параллельных чтений имеет смысл запускать. У SSD очередь глубокая, у HDD — головка одна.

min_wal_size = 1GB

Ниже этого объёма WAL-файлы не удаляются, а переиспользуются — меньше работы файловой системе.

max_wal_size = 4GB

Порог, после которого начинается контрольная точка. Больше — реже, но дольше восстановление после сбоя.

max_worker_processes = 4

Общий потолок фоновых процессов: параллельные запросы, логическая репликация, расширения.

max_parallel_workers_per_gather = 2

Сколько процессов помогает одному запросу. Слишком много — и параллельные планы вытеснят обычные запросы.

max_parallel_workers = 4

Потолок параллельных исполнителей на всю базу.

max_parallel_maintenance_workers = 2

Ускоряет CREATE INDEX и VACUUM, не трогая обычные запросы.

huge_pages = off

Большие страницы экономят память под таблицу страниц. Имеет смысл от 32 ГБ и требует настройки vm.nr_hugepages.