diff --git a/tradein-mvp/backend/data/sql/240_trade_in_estimates_retain_until.sql b/tradein-mvp/backend/data/sql/240_trade_in_estimates_retain_until.sql index 93693455..e9b0cb67 100644 --- a/tradein-mvp/backend/data/sql/240_trade_in_estimates_retain_until.sql +++ b/tradein-mvp/backend/data/sql/240_trade_in_estimates_retain_until.sql @@ -48,9 +48,29 @@ -- строки со строкой в payments опосредованно через predicate purge-джобы, -- сама таблица payments здесь не читается). -- Apply after: 233_payments.sql. +-- +-- ── lock_timeout — выставлен, хотя гейт (scripts/check-migration-lock-timeout.py) +-- этот файл не проверяет ──────────────────────────────────────────────────── +-- Порог гейта для tradein (NN >= 250) — артефакт: назначен по номеру аварийной +-- миграции 250, которую затем сняли с деплоя (#2792, 29f10002). Фактический +-- максимум применённого на main — 239, то есть НИ ОДНА миграция в диапазоне +-- 240-249 (этот файл включительно) гейтом не проверяется вообще — "проверено +-- новых миграций: 0" в логе означает "не проверено ни одного файла", а не +-- "все чисты". Сама функция scan() внутри гейта, если прогнать её без +-- порогового отсечения, помечает ALTER TABLE ниже как блокирующий DDL без +-- lock_timeout. `trade_in_estimates` — самая горячая таблица стека (история, +-- история сотрудников, каждое чтение/PDF оценки); на этой БД уже наблюдались +-- открытые транзакции на 46 и 22 часа. Ждущая ACCESS EXCLUSIVE-блокировка +-- встаёт в очередь ПЕРЕД новыми запросами — за ней начинают ждать обычные +-- SELECT приложения (см. `sql.md` § lock_timeout). На 1058 строках сам DDL +-- мгновенный — риск не в исполнении, а в ожидании чужой блокировки. Красный +-- деплой по таймауту — осознанно принятый в проекте размен (честный отказ +-- лучше тихой очереди перед приложением). НЕ убирать как "гейт же не просит". BEGIN; +SET LOCAL lock_timeout = '5s'; + ALTER TABLE trade_in_estimates ADD COLUMN IF NOT EXISTS retain_until timestamptz;