chore(db): Postgres tradein уходит со стоковых настроек — конфиг в compose #3012

Merged
lekss361 merged 1 commit from chore/2991-postgres-config into main 2026-08-20 20:53:55 +00:00

View file

@ -125,6 +125,70 @@ services:
# тяжёлых PostGIS-сортировок бэктеста/эстиматора + autovacuum)
mem_limit: 3g
memswap_limit: 3g
# ⚠️ При переезде на выделенный сервер (#2989) mem_limit поднимать ДО правки
# shared_buffers, а не после: лимит контейнера срабатывает РАНЬШЕ postgresql.conf,
# и shared_buffers=16GB при mem_limit=3g даёт OOM-kill на старте. Целевое на
# 64 ГБ — 40-48g, а не 64g: нужен запас под page cache ВНЕ контейнера.
shm_size: 512m
# /dev/shm по умолчанию 64 МБ. Параллельные воркеры кладут туда shared memory
# segments; на тяжёлых PostGIS-сортировках это «could not resize shared memory».
#
# ── Конфигурация Postgres (#2991) ─────────────────────────────────────────
# До этого контейнер шёл на ПОЛНОСТЬЮ стоковых настройках. Замер прода 2026-08-20:
# 169 млрд blks_read за 91,75 сут ≈ 175 МБ/с мимо кеша при shared_buffers=128 МБ.
#
# Значения подобраны под ТЕКУЩИЙ сервер и НЕ выходят за mem_limit=3g.
# После переезда пересчитать под 64 ГБ.
command:
- postgres
# Память. 768MB shared_buffers — 6× от стоковых 128MB, с запасом внутри 3g
# (idle-замер контейнера был 292 МБ, work_mem-спайки и autovacuum сверху).
- -c
- shared_buffers=768MB
# effective_cache_size — подсказка планировщику, НЕ аллокация. На хосте
# MemAvailable 6,1 ГБ, поэтому 6GB честно отражает доступный page cache.
- -c
- effective_cache_size=6GB
- -c
- work_mem=16MB
# maintenance_work_mem: autovacuum по listings идёт 193 раза в сутки,
# с 64MB каждый проход перечитывает индексы лишними итерациями.
- -c
- maintenance_work_mem=256MB
# Чекпойнты. ГЛАВНОЕ: 288 чекпойнтов в сутки — это ровно 24ч/288 = 5 минут,
# то есть дефолтный checkpoint_timeout, а НЕ max_wal_size. При WAL 7 ГБ/сут
# лимит в 1 ГБ дал бы 7 чекпойнтов, а не 288. Поэтому поднимаем ИМЕННО
# timeout — иначе правка max_wal_size ничего бы не изменила.
# Реже чекпойнты → реже full-page images (сейчас 55-86% всего объёма WAL).
- -c
- checkpoint_timeout=30min
- -c
- checkpoint_completion_target=0.9
# max_wal_size=4GB, а не 8GB: на диске сейчас всего 38 ГБ свободно, а pg_wal
# растёт до этого значения. При timeout=30min и 7 ГБ/сут между чекпойнтами
# накапливается ~0,15 ГБ, так что 4GB — потолок с большим запасом.
- -c
- max_wal_size=4GB
- -c
- min_wal_size=1GB
# Самая дешёвая победа при доле FPI 55-86%. zstd доступен с PG15, у нас 16.
- -c
- wal_compression=zstd
# Диск NVMe, а стоковый random_page_cost=4 — настройка под HDD: планировщик
# систематически недооценивает индексные сканы и уходит в Seq Scan.
- -c
- random_page_cost=1.1
- -c
- effective_io_concurrency=200
# pg_stat_statements: расширение есть в образе, но не подключено. Без него
# следующий разбор снова придётся вести по косвенным признакам.
# shared_preload_libraries требует рестарта — поэтому именно здесь.
- -c
- shared_preload_libraries=pg_stat_statements
- -c
- pg_stat_statements.max=5000
- -c
- pg_stat_statements.track=top
logging: *default-logging
environment:
POSTGRES_DB: tradein