Merge pull request 'chore(compose): параметризовать ресурсы postgres под переезд на новый хост' (#3058) from chore/compose-host-parameterised-resources into main
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-browser (push) Successful in 57s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-frontend (push) Successful in 58s
Deploy / build-worker (push) Successful in 58s
Deploy / build-backend (push) Successful in 1m2s
Deploy / deploy (push) Successful in 1m55s
Deploy / deploy-status (push) Successful in 2s
Deploy / perimeter-smoke (push) Successful in 18s
Deploy Trade-In / build-frontend (push) Successful in 3m29s
Deploy Trade-In / test (push) Successful in 4m25s
Deploy Trade-In / build-backend (push) Successful in 40s
Deploy Trade-In / deploy (push) Successful in 2m32s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-browser (push) Successful in 57s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-frontend (push) Successful in 58s
Deploy / build-worker (push) Successful in 58s
Deploy / build-backend (push) Successful in 1m2s
Deploy / deploy (push) Successful in 1m55s
Deploy / deploy-status (push) Successful in 2s
Deploy / perimeter-smoke (push) Successful in 18s
Deploy Trade-In / build-frontend (push) Successful in 3m29s
Deploy Trade-In / test (push) Successful in 4m25s
Deploy Trade-In / build-backend (push) Successful in 40s
Deploy Trade-In / deploy (push) Successful in 2m32s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
This commit is contained in:
commit
1c16ea45a3
2 changed files with 70 additions and 15 deletions
|
|
@ -98,7 +98,21 @@ services:
|
|||
- "127.0.0.1:5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./backend/db/init:/docker-entrypoint-initdb.d:ro
|
||||
# GENDESIGN_PG_INITDB_DIR (#2989): та же мина initdb, что описана у trade-in
|
||||
# (см. tradein-mvp/docker-compose.prod.yml) — на СВЕЖЕМ томе postgres
|
||||
# прогоняет всё из этого каталога как initdb-миграции ДО восстановления
|
||||
# дампа Site Finder. На первом старте нового хоста задать переменную на
|
||||
# ПУСТОЙ каталог — схема тогда приезжает восстановлением дампа, а не
|
||||
# initdb-цепочкой; после restore переменную снять.
|
||||
# Дефолт = текущий прод-путь, поведение Beget не меняется.
|
||||
#
|
||||
# ⚠️ Postgres этого стека (Site Finder) НЕ параметризован по mem_limit/
|
||||
# shared_buffers, в отличие от trade-in выше — сейчас у него этих лимитов
|
||||
# вовсе нет (стоковый shared_buffers=128MB на базе ~15 ГБ, wal_compression
|
||||
# off). Осознанно НЕ трогается в этой правке (#2989 — только initdb-мина,
|
||||
# добавление лимитов сервису без них — отдельная задача с отдельным риском
|
||||
# для текущего прода). См. описание PR.
|
||||
- ${GENDESIGN_PG_INITDB_DIR:-./backend/db/init}:/docker-entrypoint-initdb.d:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER}"]
|
||||
interval: 5s
|
||||
|
|
|
|||
|
|
@ -123,13 +123,28 @@ services:
|
|||
# без свапа (shared_buffers не должны уходить в swap-thrash).
|
||||
# ревью #2214: 3g (idle 656MiB — БД дороже всего при ложном OOM; work_mem-спайки
|
||||
# тяжёлых 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
|
||||
#
|
||||
# ── Переезд на выделенный сервер (#2989, репетиция 2026-08-23 на Poincare:
|
||||
# 12 потоков / 62 ГиБ / NVMe RAID1) ─────────────────────────────────────────
|
||||
# TRADEIN_PG_MEM_LIMIT — ОДНА переменная на mem_limit И memswap_limit
|
||||
# намеренно: связка «без свапа» (memswap == mem, см. обоснование выше) обязана
|
||||
# держаться и после правки, а не только на дефолте. Дефолт = ровно текущее
|
||||
# прод-значение Beget (3g) — до задания переменной поведение стека НЕ меняется.
|
||||
# ⚠️ mem_limit — потолок КОНТЕЙНЕРА, он срабатывает РАНЬШЕ postgresql.conf.
|
||||
# На новом хосте поднимать TRADEIN_PG_MEM_LIMIT ДО правки
|
||||
# TRADEIN_PG_SHARED_BUFFERS ниже — иначе shared_buffers=12GB при mem_limit=3g
|
||||
# убьёт контейнер OOM-kill'ом на самом старте. Целевое на 62 ГиБ — 44g, а
|
||||
# не 64g: нужен запас под page cache ВНЕ контейнера (это то, что реально
|
||||
# отражает effective_cache_size — не shared_buffers).
|
||||
mem_limit: ${TRADEIN_PG_MEM_LIMIT:-3g}
|
||||
memswap_limit: ${TRADEIN_PG_MEM_LIMIT:-3g}
|
||||
# TRADEIN_PG_SHM_SIZE: дефолт = текущее прод-значение (512m). Сюда ложатся
|
||||
# только DSM-сегменты параллельных планов (не буферный кеш), поэтому рост
|
||||
# /dev/shm не следует из тех же расчётов, что shared_buffers ниже — трогать
|
||||
# только если после переезда параллельные PostGIS-сортировки начнут падать
|
||||
# с «could not resize shared memory segment» (аналог #2812 в корневом
|
||||
# docker-compose.prod.yml).
|
||||
shm_size: ${TRADEIN_PG_SHM_SIZE:-512m}
|
||||
# /dev/shm по умолчанию 64 МБ. Параллельные воркеры кладут туда shared memory
|
||||
# segments; на тяжёлых PostGIS-сортировках это «could not resize shared memory».
|
||||
#
|
||||
|
|
@ -138,23 +153,39 @@ services:
|
|||
# 169 млрд blks_read за 91,75 сут ≈ 175 МБ/с мимо кеша при shared_buffers=128 МБ.
|
||||
#
|
||||
# Значения подобраны под ТЕКУЩИЙ сервер и НЕ выходят за mem_limit=3g.
|
||||
# После переезда пересчитать под 64 ГБ.
|
||||
#
|
||||
# ── Параметризация под переезд (#2989, репетиция 2026-08-23 на Poincare) ──
|
||||
# Пять параметров ниже вынесены в переменные ИМЕННО потому что они зависят
|
||||
# от размера хоста; остальные (checkpoint_timeout, wal_compression,
|
||||
# random_page_cost, pg_stat_statements и пр. ниже) от размера хоста НЕ
|
||||
# зависят — оставлены как есть. Дефолты = буквально текущие прод-значения
|
||||
# на Beget, так что до задания переменных поведение НЕ меняется ни на бит.
|
||||
# Целевые значения для нового хоста (62 ГиБ) — задавать в окружении деплоя,
|
||||
# НЕ здесь и НЕ на Beget (там 11 ГиБ, контейнер просто не поднимется):
|
||||
# TRADEIN_PG_MEM_LIMIT=44g (сначала он — см. предупреждение выше)
|
||||
# TRADEIN_PG_SHARED_BUFFERS=12GB
|
||||
# TRADEIN_PG_EFFECTIVE_CACHE_SIZE=36GB
|
||||
# TRADEIN_PG_WORK_MEM=64MB
|
||||
# TRADEIN_PG_MAINTENANCE_WORK_MEM=2GB
|
||||
# TRADEIN_PG_MAX_WAL_SIZE=16GB
|
||||
# Порядок обязателен: сначала TRADEIN_PG_MEM_LIMIT (контейнерный потолок,
|
||||
# см. выше), потом эти пять — иначе OOM-kill на старте.
|
||||
command:
|
||||
- postgres
|
||||
# Память. 768MB shared_buffers — 6× от стоковых 128MB, с запасом внутри 3g
|
||||
# (idle-замер контейнера был 292 МБ, work_mem-спайки и autovacuum сверху).
|
||||
- -c
|
||||
- shared_buffers=768MB
|
||||
- shared_buffers=${TRADEIN_PG_SHARED_BUFFERS:-768MB}
|
||||
# effective_cache_size — подсказка планировщику, НЕ аллокация. На хосте
|
||||
# MemAvailable 6,1 ГБ, поэтому 6GB честно отражает доступный page cache.
|
||||
- -c
|
||||
- effective_cache_size=6GB
|
||||
- effective_cache_size=${TRADEIN_PG_EFFECTIVE_CACHE_SIZE:-6GB}
|
||||
- -c
|
||||
- work_mem=16MB
|
||||
- work_mem=${TRADEIN_PG_WORK_MEM:-16MB}
|
||||
# maintenance_work_mem: autovacuum по listings идёт 193 раза в сутки,
|
||||
# с 64MB каждый проход перечитывает индексы лишними итерациями.
|
||||
- -c
|
||||
- maintenance_work_mem=256MB
|
||||
- maintenance_work_mem=${TRADEIN_PG_MAINTENANCE_WORK_MEM:-256MB}
|
||||
# Чекпойнты. ГЛАВНОЕ: 288 чекпойнтов в сутки — это ровно 24ч/288 = 5 минут,
|
||||
# то есть дефолтный checkpoint_timeout, а НЕ max_wal_size. При WAL 7 ГБ/сут
|
||||
# лимит в 1 ГБ дал бы 7 чекпойнтов, а не 288. Поэтому поднимаем ИМЕННО
|
||||
|
|
@ -168,7 +199,7 @@ services:
|
|||
# растёт до этого значения. При timeout=30min и 7 ГБ/сут между чекпойнтами
|
||||
# накапливается ~0,15 ГБ, так что 4GB — потолок с большим запасом.
|
||||
- -c
|
||||
- max_wal_size=4GB
|
||||
- max_wal_size=${TRADEIN_PG_MAX_WAL_SIZE:-4GB}
|
||||
- -c
|
||||
- min_wal_size=1GB
|
||||
# Самая дешёвая победа при доле FPI 55-86%. zstd доступен с PG15, у нас 16.
|
||||
|
|
@ -196,7 +227,17 @@ services:
|
|||
POSTGRES_PASSWORD: ${TRADEIN_POSTGRES_PASSWORD:?required}
|
||||
volumes:
|
||||
- tradein-postgres-data:/var/lib/postgresql/data
|
||||
- ./backend/data/sql:/docker-entrypoint-initdb.d:ro
|
||||
# TRADEIN_PG_INITDB_DIR (#2989): на СВЕЖЕМ томе postgres прогоняет ВСЁ из
|
||||
# этого каталога как initdb-миграции ДО восстановления дампа — 249 миграций
|
||||
# отработают первыми и засеют данные (`scrape_schedules` 157 строк,
|
||||
# `tradein_users` 13, `deals` 80 — `003_seed_deals`/`193_tradein_users_seed`),
|
||||
# а дамп идёт с `--clean --if-exists` и ляжет поверх (см. репетицию переноса
|
||||
# 2026-08-23, vault fixes/Bug_Migration_Window_Operational_Blockers_OPEN п.2).
|
||||
# На первом старте нового хоста задать переменную на ПУСТОЙ каталог — схема
|
||||
# тогда приезжает восстановлением дампа, а не initdb-цепочкой; после
|
||||
# restore переменную снять, дальше работает как обычно.
|
||||
# Дефолт = текущий прод-путь, поведение Beget не меняется.
|
||||
- ${TRADEIN_PG_INITDB_DIR:-./backend/data/sql}:/docker-entrypoint-initdb.d:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${TRADEIN_POSTGRES_USER:-tradein}"]
|
||||
interval: 10s
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue