gendesign/ops/crontab-poincare.cron
bot-backend ec6181b7b3
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
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
chore(ops): restore-дрель для базы tradein — она не покрывалась вовсе
Дрель восстановления стоит в cron с #3085, но её строка берёт только
`gendesign_*`. База tradein — клиентские оценки, листинги, дома, сделки —
автоматически на восстановимость не проверялась ни разу: дампы снимались,
уезжали в S3, и никто не знал, разворачиваются ли они.

Сам `ops/restore-drill.sh` менять не пришлось — он с самого начала умеет оба
проекта: находит globals по своей схеме имён (`tradein-globals-<ts>`),
подставляет свой список таблиц для сверки. Не хватало ровно строки в cron.

Прогнал на боевом дампе 27.08 перед тем, как добавлять (оповещение заглушено,
чтобы не слать ложную тревогу):

    tradein-20260827-111102.sql.gz, 343 МБ → 58 c
    GRANT-ы применены, материализованные представления обновлены
    PostGIS 3.4.3, таблиц в public: 76
    listings 109978 · listing_sources 106704 · deals 108623
    houses 10400 · trade_in_estimates 1121

Сверка с боевой базой: houses, listings, deals, osm_poi сходятся точно;
trade_in_estimates и user_events больше на проде ровно на строки, созданные
ПОСЛЕ снятия дампа. То есть дамп верен.

Еженедельно, а не раз в месяц: две минуты работы против месяца, в течение
которого битый дамп остаётся незамеченным. Понедельник 03:00 — после дрели
gendesign (02:15 первого числа) и до ночных бэкапов в 03:30.
2026-08-27 14:57:40 +03:00

82 lines
8.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# crontab ПРИНИМАЮЩЕГО хоста (Selectel Poincare, 188.124.37.140) — после 30.08.
#
# Устанавливать СРАЗУ после того, как стек поднялся и смоук прошёл:
# mkdir -p /opt/gendesign/logs
# crontab /opt/gendesign/ops/crontab-poincare.cron
# crontab -l # сверить
#
# Перед установкой в /etc/default/ должны лежать (root-owned, chmod 600,
# НЕ в git, переносятся руками с предыдущего хоста или создаются заново):
# /etc/default/gendesign-backup — S3_ENDPOINT/S3_BUCKET/S3_ACCESS_KEY/S3_SECRET_KEY
# (см. ops/gendesign-backup.default.example)
# /etc/default/tradein-backup — свои S3_*, либо отсутствует (тогда
# backup-tradein-db.sh падает на общий
# /etc/default/gendesign-backup выше)
# Без них ops/backup.sh и backup-tradein-db.sh теперь падают громко (#3085),
# а не молча пишут локальный бэкап.
#
# ⚠️ САМЫЙ ОПАСНЫЙ ПРОПУСК ВСЕГО ПЕРЕЕЗДА. Если этот файл не установить,
# на новом хосте НЕ БУДЕТ НИ ОДНОГО БЭКАПА — ни tradein, ни gendesign. И узнать
# об этом будет неоткуда: сторож пропущенных прогонов (check-backup-staleness)
# сам живёт в этом же crontab'е, то есть его тоже не будет. Отсутствие бэкапов
# обнаружится в момент, когда они понадобятся.
#
# Времена оставлены те же, что были на Beget — чтобы не гадать, изменилось ли
# поведение из-за переезда или из-за нового расписания. Подгонять окна имеет
# смысл ПОСЛЕ того, как всё поедет стабильно.
# ── Бэкапы обоих кластеров ──────────────────────────────────────────────────
# Off-box выгрузка в S3 включается через /etc/default/tradein-backup и
# /etc/default/gendesign-backup — файлы НЕ переезжают сами (в git их нет и не
# должно быть), их нужно перенести руками. Без них оба скрипта падают ГРОМКО
# (exit 1, дамп не снимается вовсе) — см. #3085; они больше НЕ пишут молча
# локальный бэкап.
30 3 * * * bash /opt/gendesign/ops/backup.sh >> /opt/gendesign/logs/gendesign-backup.log 2>&1
30 4 * * * bash /opt/gendesign/tradein-mvp/deploy/backup-tradein-db.sh >> /opt/gendesign/logs/tradein-backup.log 2>&1
# Сторожа пропущенных прогонов, порог 26ч. Едут вместе со своими бэкапами:
# сторож должен жить там же, где sentinel, иначе он сторожит файл, который
# никто не обновляет, и кричит вечно.
0 * * * * bash /opt/gendesign/ops/check-backup-staleness.sh /opt/gendesign/backups/.last_success 26 "gendesign main backup" >> /opt/gendesign/logs/backup-staleness.log 2>&1
0 * * * * bash /opt/gendesign/ops/check-backup-staleness.sh /opt/gendesign/backups/tradein/.last_success 26 "tradein backup" >> /opt/gendesign/logs/backup-staleness.log 2>&1
# ── Restore-дрель, раз в месяц (#3085) ───────────────────────────────────────
# Восстановимость дампа никогда не проверялась автоматически — только
# ручными прогонами. 1-е число месяца, 02:15 — до ночных бэкапов (03:30/04:30)
# и до обогащения/геокодинга (05:00-05:45), не пересекается ни с чем.
# Берёт САМЫЙ СВЕЖИЙ на тот момент main-дамп; ops/restore-drill.sh сам найдёт
# рядом лежащий globals-файл и сам снесёт свой временный контейнер — прод не
# трогает никогда (см. заголовок скрипта).
15 2 1 * * bash -c 'f=$(ls -t /opt/gendesign/backups/gendesign_[0-9]*.sql.gz 2>/dev/null | head -1); if [ -n "$f" ]; then bash /opt/gendesign/ops/restore-drill.sh "$f"; else echo "no gendesign dump found to drill"; exit 1; fi' >> /opt/gendesign/logs/restore-drill.log 2>&1
# Та же дрель для базы tradein — она НЕ покрывалась строкой выше (#2203).
# Строка выше берёт только `gendesign_*`, то есть восстановимость базы
# клиентских оценок автоматически не проверялась вовсе: ни листинги, ни дома,
# ни сами оценки. Замер 27.08: дамп 343 МБ разворачивается за 58 c и сходится
# с боевой базой построчно (houses 10400, listings 109978, deals 108623 —
# расхождения только по строкам, созданным ПОСЛЕ снятия дампа).
#
# Еженедельно, а не раз в месяц: две минуты работы против месяца, в течение
# которого битый дамп остаётся незамеченным. Понедельник 03:00 — после
# монтажной дрели gendesign (02:15 первого числа, ей хватает форы даже когда
# первое выпадает на понедельник) и до ночных бэкапов в 03:30.
0 3 * * 1 bash -c 'f=$(ls -t /opt/gendesign/backups/tradein/tradein-[0-9]*.sql.gz 2>/dev/null | head -1); if [ -n "$f" ]; then bash /opt/gendesign/ops/restore-drill.sh "$f"; else echo "no tradein dump found to drill"; exit 1; fi' >> /opt/gendesign/logs/restore-drill.log 2>&1
# ── Обогащение и геокодирование (ходят в tradein-backend) ───────────────────
0 5 * * * cd /opt/gendesign/tradein-mvp && docker exec tradein-backend python -m scripts.backfill_houses_dadata --limit 100 --priority both >> /opt/gendesign/logs/dadata-backfill.log 2>&1
30 5 * * * cd /opt/gendesign/tradein-mvp && docker exec tradein-backend python -m scripts.geocode_deals_from_houses --limit 50000 >> /opt/gendesign/logs/deals-geocode.log 2>&1
45 5 * * * cd /opt/gendesign/tradein-mvp && docker exec tradein-backend python -m scripts.geocode_deals_nominatim --limit 5000 >> /opt/gendesign/logs/deals-nominatim.log 2>&1
# ── Уборка докера ───────────────────────────────────────────────────────────
# СВОЯ запись, не «переехавшая»: на Beget она чистит тома CI-раннеров, здесь —
# образы продуктового стека. Нужны обе, на обоих хостах.
0 4 * * 0 bash /opt/gendesign/ops/docker-prune.sh >> /opt/gendesign/logs/docker-prune.log 2>&1
# ── Логи: /opt/gendesign/logs, а не /tmp ────────────────────────────────────
# На Beget половина записей писала в /tmp — он чистится при перезагрузке, и
# именно поэтому историю отказов бэкапов там восстановить не удавалось.
# Каталог создать до установки crontab: mkdir -p /opt/gendesign/logs
#
# ── ЧЕГО ЗДЕСЬ НЕТ ──────────────────────────────────────────────────────────
# backup-forgejo.sh + его сторож — Forgejo остаётся на Beget
# (см. ops/crontab-beget.cron)