fix(ops): дрилл восстановления ждал БД по сокету и умирал на старте настоящего сервера #3026

Merged
lekss361 merged 1 commit from fix/2203-restore-drill-readiness into main 2026-08-21 17:12:00 +00:00
Owner

Как нашлось

Не по чтению кода. Я впервые запустил ops/restore-drill.sh на проде на живом дампе tradein-20260821-013001.sql.gz (307 МБ) — акцептанс #2203 «restore-тест в чистую БД», который до сегодня ни разу не выполнялся. Дрилл упал через 6 секунд:

[2026-08-21T12:26:22Z] Restoring dump into 'drill' (ON_ERROR_STOP=1 — any real error aborts the drill)
FATAL:  terminating connection due to administrator command
server closed the connection unexpectedly
        This probably means the server terminated abnormally
[2026-08-21T12:26:24Z] Cleaning up container restore-drill-2833737-1787315178

Причина

ops/restore-drill.sh:116 проверял готовность через docker exec … pg_isready -U postgres — это unix-сокет. Образ postgres во время инициализации поднимает временный сервер, и он на сокете уже отвечает «accepting connections». Проба зеленела посреди initdb, восстановление начиналось в этот временный сервер и получало SIGTERM в тот момент, когда entrypoint гасил его, чтобы поднять настоящий.

Временный сервер не слушает TCP, поэтому -h 127.0.0.1 зеленеет только на настоящем сервере.

Проверка

С правкой тот же дамп на той же машине проходит инициализацию, восстанавливает схему и данные и доходит до сборки индексов (прогон шёл в момент открытия PR). bash -n чисто.

Один баг в трёх местах

Место Состояние
.forgejo/workflows/ci-tradein.yml:137-141 уже вылечено ранее, там же в комментарии описана причина
.forgejo/workflows/deploy-tradein.yml:718-721 тот же дефект, чинится в PR #3011 — здесь не трогаю
ops/restore-drill.sh:116 этот PR

В деплое последствие тяжелее, чем здесь: там проба по сокету зеленеет посреди initdb, часовой schema_already_present видит listings (создаётся миграцией 002, то есть почти сразу) и уводит деплой в ветку baseline — все 249 миграций помечаются applied без прогона. Разбор в ревью PR #3011.

Blast radius

Нулевой для прода: скрипт поднимает одноразовый контейнер на анонимном хранилище, слушает только 127.0.0.1, боевые тома не монтирует и сносит контейнер в любом исходе. Меняется одна строка условия + комментарий, объясняющий, почему -h 127.0.0.1 тут несущий, а не косметика.

Refs #2203, #2989

## Как нашлось Не по чтению кода. Я впервые запустил `ops/restore-drill.sh` на проде на живом дампе `tradein-20260821-013001.sql.gz` (307 МБ) — акцептанс #2203 «restore-тест в чистую БД», который до сегодня ни разу не выполнялся. Дрилл упал через **6 секунд**: ``` [2026-08-21T12:26:22Z] Restoring dump into 'drill' (ON_ERROR_STOP=1 — any real error aborts the drill) FATAL: terminating connection due to administrator command server closed the connection unexpectedly This probably means the server terminated abnormally [2026-08-21T12:26:24Z] Cleaning up container restore-drill-2833737-1787315178 ``` ## Причина `ops/restore-drill.sh:116` проверял готовность через `docker exec … pg_isready -U postgres` — это **unix-сокет**. Образ postgres во время инициализации поднимает временный сервер, и он на сокете уже отвечает «accepting connections». Проба зеленела посреди `initdb`, восстановление начиналось в этот временный сервер и получало SIGTERM в тот момент, когда entrypoint гасил его, чтобы поднять настоящий. Временный сервер **не слушает TCP**, поэтому `-h 127.0.0.1` зеленеет только на настоящем сервере. ## Проверка С правкой тот же дамп на той же машине проходит инициализацию, восстанавливает схему и данные и доходит до сборки индексов (прогон шёл в момент открытия PR). `bash -n` чисто. ## Один баг в трёх местах | Место | Состояние | |---|---| | `.forgejo/workflows/ci-tradein.yml:137-141` | уже вылечено ранее, там же в комментарии описана причина | | `.forgejo/workflows/deploy-tradein.yml:718-721` | тот же дефект, чинится в PR #3011 — здесь **не трогаю** | | `ops/restore-drill.sh:116` | этот PR | В деплое последствие тяжелее, чем здесь: там проба по сокету зеленеет посреди initdb, часовой `schema_already_present` видит `listings` (создаётся миграцией 002, то есть почти сразу) и уводит деплой в ветку `baseline` — все 249 миграций помечаются applied **без прогона**. Разбор в ревью PR #3011. ## Blast radius Нулевой для прода: скрипт поднимает одноразовый контейнер на анонимном хранилище, слушает только `127.0.0.1`, боевые тома не монтирует и сносит контейнер в любом исходе. Меняется одна строка условия + комментарий, объясняющий, почему `-h 127.0.0.1` тут несущий, а не косметика. Refs #2203, #2989
lekss361 added 1 commit 2026-08-21 12:43:06 +00:00
fix(ops): дрилл восстановления ждал БД по сокету и умирал на старте настоящего сервера
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
b588278923
`ops/restore-drill.sh` проверял готовность через `pg_isready -U postgres`, то
есть по unix-сокету. Образ postgres во время инициализации поднимает временный
сервер, который на сокете уже отвечает "accepting connections". Проба зеленела
посреди initdb, восстановление начиналось в этот временный сервер и погибало,
как только entrypoint гасил его ради настоящего:

    [12:26:22Z] Restoring dump into 'drill' (ON_ERROR_STOP=1 ...)
    FATAL:  terminating connection due to administrator command
    server closed the connection unexpectedly

Воспроизведено на проде 2026-08-21 на живом дампе `tradein-20260821-013001`:
падение через 6 секунд после старта. С `-h 127.0.0.1` тот же дамп проходит
восстановление и доходит до сборки индексов — временный сервер TCP не слушает,
поэтому по TCP проба зеленеет только на настоящем сервере.

Ровно та же проба и ровно по той же причине уже стоит в
`.forgejo/workflows/ci-tradein.yml:137-141`. Тот же дефект живёт и в
`.forgejo/workflows/deploy-tradein.yml:718-721` — там его чинят в PR #3011,
здесь не трогаю.

Refs #2203, #2989
lekss361 merged commit 1202804268 into main 2026-08-21 17:12:00 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3026
No description provided.