fix(tradein): миграция 267 — lock_timeout, как требует гейт #2752
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m36s

Гейт `check-migration-lock-timeout.py` в ci.yml поймал правильно: `ADD COLUMN`
без `SET LOCAL lock_timeout` — блокирующий DDL.

Мой комментарий в первой версии был вдобавок обманчив: «блокировки не берёт,
ADD COLUMN без DEFAULT не переписывает таблицу». Переписывания действительно
нет, но ACCESS EXCLUSIVE берётся, и опасно не удержание лока, а ОЖИДАНИЕ его
выдачи — ждущий DDL встаёт в очередь перед новыми запросами приложения к той же
таблице. Так миграция 250 простояла 29 минут за чужой psql-сессией. Переписал
комментарий под то, что происходит на самом деле.

Refs #2899, #2752
This commit is contained in:
bot-backend 2026-08-19 15:02:23 +05:00
parent 2c852bd13b
commit 9f17983689

View file

@ -6,15 +6,25 @@
-- позицию по сохранённому top-10 нельзя — это другая популяция, поэтому значение
-- обязано персиститься вместе с оценкой.
--
-- smallint: диапазон значений 1..99 по построению (`_market_percentile` зажимает
-- края — «0-й перцентиль» читался бы как «дешевле всех на свете», хотя означает лишь
-- край выборки). NULL = когорта меньше MARKET_PERCENTILE_MIN_N (15) либо оценки нет.
-- smallint: диапазон 1..99 по построению (`_market_percentile` зажимает края —
-- «0-й перцентиль» читался бы как «дешевле всех на свете», хотя означает лишь край
-- выборки). NULL = когорта меньше MARKET_PERCENTILE_MIN_N (15) либо оценки нет.
-- Бэкфилла нет и быть не может: позицию старых строк восстановить не из чего.
--
-- Идемпотентно: IF NOT EXISTS. Блокировки не берёт (ADD COLUMN без DEFAULT в PG 11+
-- не переписывает таблицу).
-- ПРО ЛОКИ (#2752). ADD COLUMN без DEFAULT в PG 11+ не переписывает таблицу и держит
-- ACCESS EXCLUSIVE миллисекунды — но ЖДАТЬ его выдачи может сколько угодно, и всё это
-- время ждущий DDL стоит в очереди ПЕРЕД новыми запросами приложения к той же таблице.
-- Ровно так миграция 250 встала на 29 минут за чужой psql-сессией. lock_timeout
-- ограничивает только ожидание: не дождались — красный деплой вместо тихой очереди.
BEGIN;
SET LOCAL lock_timeout = '5s';
ALTER TABLE trade_in_estimates
ADD COLUMN IF NOT EXISTS market_percentile smallint;
COMMENT ON COLUMN trade_in_estimates.market_percentile IS
'#2899: доля аналогов дешевле этой квартиры, 1..99. NULL — когорта < 15 лотов. '
'НЕ location_index_pct (тот про район против медианы города).';
COMMIT;