From e9b0a9edbce185adc0b2143d5849dcb18312773c Mon Sep 17 00:00:00 2001 From: vitya Date: Thu, 28 May 2026 19:50:13 +0300 Subject: [PATCH] =?UTF-8?q?docs(tasks):=20restore-elasticsearch-indices-bo?= =?UTF-8?q?oks-vds=20=E2=80=94=20books=20VDS=20ES=20stack=2033=20=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prod incident в репо books: slovo поиск товаров+EPZ лежит. `elasticsearch.kzntsv.site` отвечает 200 на _cluster/health (green, 0 active shards, 0 docs); source `elasticold.kzntsv.site` (Windows rollback) — полный набор: epz 820604 / products 105922 / artmone 2621. Окно поломки 27.05 10:24 → 28.05 13:59, в нём шла bookva-tenant-cutover-prep (bookva-es stack 37 создавался) — возможный конфликт. Playbook в task-файле: forensics (Portainer stack 33 audit + docker volume inspect) → snapshot restore из kreknin repo если post-25.05 snapshot с непустыми индексами → иначе reindex повторно по migrate-elasticsearch-to-books-vds procedure (730MB ~5-10 мин). После — restart 4 consumer'ов. NEXT_SESSION.md перезаписан, restore поставлен как приоритет 1, carried items (registry GC, netplan artifacts, board-viewer-build) сохранены. Co-Authored-By: Claude Opus 4.7 (1M context) --- .tasks/NEXT_SESSION.md | 189 ++++++++++++------ .tasks/STATUS.md | 12 ++ ...restore-elasticsearch-indices-books-vds.md | 82 ++++++++ 3 files changed, 219 insertions(+), 64 deletions(-) create mode 100644 .tasks/restore-elasticsearch-indices-books-vds.md diff --git a/.tasks/NEXT_SESSION.md b/.tasks/NEXT_SESSION.md index 29f2900..5d57bec 100644 --- a/.tasks/NEXT_SESSION.md +++ b/.tasks/NEXT_SESSION.md @@ -1,72 +1,133 @@ --- -_last_updated_: 2026-05-28T14:15:00+03:00 -session_id: 2026-05-28-vds-kzntsv-network-stack-mismatch +_last_updated_: 2026-05-28T16:30:00+03:00 +session_id: 2026-05-28-prod-epz-search-outage-admin-handoff --- # Next session handoff -## Контекст сессии - -vds-kzntsv (89.253.255.94) был недоступен по сети ~05:45–08:30 MSK 28 мая 2026 (~2.5ч активного outage). С 08:43 жил на эфемерной статике (через VNC) до окончательного fix хостером в **13:52 MSK** — они переписали конфиг через свой `start/ipadd` procedure, мы предварительно masked netplan + systemd-networkd через SSH. - -**Revised RCA** (после resolution): наш сетевой стек был mixed (netplan+networkd поверх provider's expected ifupdown). 8 дней работало потому что networkd сам получал DHCP. Когда что-то на стороне Rusonyx разорвало DHCP-binding (28.05 утром) — их auto-recovery `start/ipadd` не смогла применить static config, потому что networkd «держал» eth0. Fix = mask netplan/networkd, оставить только ifupdown. - -## LIVE сейчас - -- **vds-kzntsv** работает на чистом ifupdown stack: `/etc/network/interfaces.d/ifcfg-eth0` (provider-managed), netmask **/18** (`255.255.192.0`), gw `89.253.192.1`. `netplan` + `systemd-networkd*` masked. -- **24 docker контейнера up** включая весь стек (gitea, registry, verdaccio, postgres, mariadb, mongo, redis, owncloud/oCIS, modulair-rag×4, mssql, board-viewer, traefik, portainer, ntfy, vds-ops-mcp, vds-docker-proxy-ro). **1 unhealthy** — `board-viewer-build` (предсуществующий, не связан с инцидентом). -- **Диск 79%** (118G/158G) — после quick GC сегодня утром (build cache 10.6G + dangling 0.3G + container logs ~3G truncated). Registry GC ~20G storage **не сделан** — pending. -- **Wiki, memory, STATUS** — обновлены с финальным RCA. Commit за сессию pending (см. ниже). - -## Что делать на следующей сессии (по приоритету) - -### 1. Cleanup netplan-artifacts (опционально, низкий приоритет) - -После resolution на сервере остались netplan конфиги (не активны, netplan masked, но лежат): - -- `/etc/netplan/01-eth0.yaml` — мы создали 28.05 утром при попытке fix через netplan -- `/etc/netplan/50-cloud-init.yaml` — от cloud-init -- `/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg` — мы создали (с опечаткой `disbaled` в одной из попыток, потом исправили) - -Можно удалить или оставить — они не влияют (netplan masked). **Если** соберёмся когда-нибудь снять mask с netplan — следует тогда clean up. Сейчас не трогаем. - -### 2. Registry GC (~20G storage reclaim — pending) - -Из task #2 в TaskList. Окно read-only=true на 5-15 мин. **Делать только в low-traffic окно** — registry push/pull временно недоступен. - -```bash -# на VDS -sudo docker exec registry registry garbage-collect --delete-untagged=true /etc/docker/registry/config.yml -# проверка размера до/после -sudo du -sh /opt/stacks/registry -``` - -### 3. board-viewer-build unhealthy — разбор - -Предсуществующий, не связан с инцидентом. Если беспокоит — `sudo docker logs board-viewer-build | tail -50` + проверить healthcheck в compose. Иначе можно `--no-healthcheck` если он не нужен в running container. - -### 4. SLA / RCA от Rusonyx — follow up (опционально) - -В первом нашем тикете запрашивали технический RCA + SLA-компенсацию. User просил это не муссировать. На усмотрение — можно через несколько дней спросить «приходил ли формальный RCA», но force'ить не нужно. - -## Спроси user'а - -- **Registry GC** — окно ~5-15 мин в read-only=true, делать ночью или сейчас? -- **Cleanup netplan artifacts** — оставить как есть или зачистить `/etc/netplan/*`? (Low-priority) -- **Push wiki + memory + tasks** — push'нуть commit'нутые изменения в origin? (Per project-discipline нужен per-session grant, пока не давал) - -## Не делать (preemptive guards) - -- **НЕ unmask netplan/systemd-networkd** на vds-kzntsv. Anti-pattern для Rusonyx (см. concept). -- **НЕ редактировать `/etc/network/interfaces` или `/etc/network/interfaces.d/ifcfg-eth0`** — provider's start/ipadd procedure перезапишет при любых их manipulations с VM (resize, network reset). -- **НЕ reboot VDS без необходимости** — конфиг теперь правильный, но любой их network-action может что-то поменять, и проверить новое состояние придётся через VNC. -- **НЕ делать registry GC без `read-only=true` mode** — rogue push может corrupt'ить blobs. - -## Memory updates за сессию - -- **UPDATE** `vds-kzntsv-rusonyx-network-recovery.md` — переписан с revised RCA: provider stack = ifupdown, netmask /18, canonical bootstrap-step `mask netplan/networkd`. Anti-pattern: netplan на Rusonyx. -- **Уточнение паттерна:** при сетевых проблемах на Rusonyx VDS первым делом проверять что стек = ifupdown (не netplan). `systemctl is-enabled netplan systemd-networkd networking` — должно быть `masked masked enabled`. +_Сессия: новая admin task `restore-elasticsearch-indices-books-vds` +заведена по итогам диагностики prod outage в репозитории `books`._ ## Recent commits -- (pending — этот сеанс ещё не commit'ил; wiki + memory + STATUS + NEXT_SESSION готовы к одному commit'у). +- (pending — этот сеанс ничего не commit'ил; .tasks/STATUS.md + + .tasks/restore-elasticsearch-indices-books-vds.md + + .tasks/NEXT_SESSION.md готовы к одному commit'у) + +## Контекст инцидента + +В репо `books` сегодня диагностировали prod outage поиска slovo (товары + +EPZ): `/api/{epz,products}/search` возвращают 500 `index_not_found_exception`. +Эндпоинты лезут на canonical ES `https://elasticsearch.kzntsv.site/` (books +VDS Portainer stack 33) — и не находят там ни `epz`, ни `products`. + +**curl `_cat/indices`** на двух сторонах: + +- `elasticold.kzntsv.site` (Windows rollback, live) — **полный набор**: epz + 820604 / products 105922 / artmone 2621. +- `elasticsearch.kzntsv.site` (books VDS stack 33) — **0 индексов**, cluster + green, 0 active primary shards. Даже `read_me` плейсхолдер из миграции + 25.05 пропал. + +**Окно поломки:** 27.05 10:24 MSK (последний рестарт `books-api`/`books-web`, +ошибок в их stderr ещё не было) → 28.05 13:59 UTC (первая фиксация +`index_not_found_exception` в логах). В этом окне на books VDS шла работа +`bookva-tenant-cutover-prep` (Step 2 — 9 Portainer stacks создавались, в т.ч. +**bookva-es=37**). Возможный конфликт volume/audit на stack 33 — выяснить +forensics'ом. + +Snapshot repo `kreknin` на target ES зарегистрирован (location=/snapshots). +`pre-migration-2026-05-25` снапшот был только с `read_me` placeholder, для +restore не годится. Но **в kreknin могут быть post-25.05 daily snapshots** +(`books-vds-backup-daily-kreknin` пайплайн closed 25.05) — проверить +`_snapshot/kreknin/_all?verbose=true`, искать снимок с непустыми +epz/products/artmone. + +## LIVE сейчас + +- **books-app prod**: поиск slovo (товары + EPZ) лежит, пользователи видят + 500 на `/epz/search`. Заведена `epz-search-seller-pin-tenant` ⚪ в `books` + репо как side-issue (хардкод `findByPk(1)`), но **не блокер этого outage'а**. +- **Source ES** на Windows host жив (`elasticold.kzntsv.site` через traefik + basicAuth) — не disabled per migration policy, годится для повторного + reindex. +- **Target ES** на books VDS жив (cluster green, отвечает 200 на + `_cluster/health`), но индексов нет. + +## Что делать на следующей сессии (по приоритету) + +### 1. **Forensics + restore** — `restore-elasticsearch-indices-books-vds` ⚪ + +Полный playbook + acceptance в task-файле. Старт: + +```bash +# на books VDS — Portainer audit stack 33 +curl -fsS -H "X-API-Key: $PORTAINER_TOKEN" \ + https://portainer.kzntsv.site/api/stacks/33 | jq '.UpdateDate, .Status' +sudo docker volume inspect /usr/docker/elasticsearch/data +sudo ls -lah /usr/docker/elasticsearch/data/nodes/0/indices/ 2>/dev/null +``` + +Затем — `curl _snapshot/kreknin/_all?verbose=true` на target → если post-25.05 +snapshot с непустыми индексами есть → restore. Иначе — reindex повторно +по `migrate-elasticsearch-to-books-vds.md` Steps 4–6 (730MB, ~5–10 мин). + +После — `docker restart books-api books-web books-task-runner books-job-scheduler` +(на случай stale connection pool у consumer'ов). + +### 2. **(carried) Registry GC** — ~20G storage reclaim + +Из прошлого handoff'а, всё ещё pending. Read-only=true ~5–15 мин: + +```bash +sudo docker exec registry registry garbage-collect --delete-untagged=true /etc/docker/registry/config.yml +sudo du -sh /opt/stacks/registry +``` + +### 3. **(carried) Cleanup netplan artifacts** — low priority, оставить + +`/etc/netplan/01-eth0.yaml`, `/etc/netplan/50-cloud-init.yaml`, +`/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg` — не влияют (netplan +masked), оставить пока кто-нибудь не решит снять mask. + +### 4. **(carried) board-viewer-build unhealthy** — пред-инцидент + +Не связан с outage'ом. Опционально разобрать через +`sudo docker logs board-viewer-build | tail -50`. + +## Спроси user'а + +- **ES restore сейчас или подождать low-traffic окно?** Reindex 730MB / 5–10 + мин, slovo поиск всё это время уже лежит — задержка не критична для бэка, + только для пользователей. Snapshot restore (если есть свежий) — быстрее. +- **Push** wiki + memory + tasks — push'нуть commit'нутые изменения в origin? + (Per project-discipline нужен per-session grant, пока не давал.) +- **Cleanup netplan artifacts** — оставить или зачистить? (carried) + +## Не делать (preemptive guards) + +- **НЕ stop / recreate Portainer stack 33** до forensics. Если volume + накосячил из-за recreate — повторный recreate может затереть оставшиеся + следы (logs, audit). +- **НЕ удалять `kreknin` repo / старые snapshot'ы** до confirm'а что restore + не нужен. `pre-migration-2026-05-25` сам по себе не годится, но **в repo + могут лежать другие snapshots** от daily пайплайна. +- **НЕ менять consumer config'и в `books`** на elasticold обратно. На VPS + bind-mount уже sed'нут на canonical с 25.05 — пусть остаётся. Восстановим + данные на canonical endpoint'е, не двигаем endpoint. +- **НЕ unmask netplan/systemd-networkd** на vds-kzntsv (carried — anti-pattern + для Rusonyx). +- **НЕ reboot VDS без необходимости** (carried). +- **НЕ делать registry GC без `read-only=true`** (carried). + +## Memory updates за сессию + +- (нет новых memory-файлов — incident self-contained в task file с pointers + на migration playbook) + +## Wiki ингест + +- (нет на этом раунде — после restore, если forensics выявит конкретный + trigger «X recreate стирает Y volume», стоит ингестнуть в + `.wiki/concepts/portainer-stack-volume-pitfalls.md` или подобное; пока + гипотеза только) diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 53e3c98..fc3bace 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,4 +1,5 @@ # Admin Task Board +_Updated: 2026-05-28 — **prod incident**: books-app slovo поиск товаров + EPZ сломаны, ES `elasticsearch.kzntsv.site` (books VDS stack 33) пуст (0 индексов из 3 ожидаемых; source `elasticold.kzntsv.site` rollback — все 928k docs на месте). Заведена ⚪ `restore-elasticsearch-indices-books-vds`. Окно поломки: 27.05 10:24 → 28.05 13:59, в этом окне шла работа bookva-cutover-prep (bookva-es stack 37 создавался) — возможный конфликт. См. таску для playbook'а._ _Updated: 2026-05-28 — **vds-kzntsv network-stack mismatch RESOLVED** в 13:52 MSK. Сначала ~2.5ч активного outage (05:45-08:30) + ~5.5ч на эфемерной статике до окончательного fix хостером. Revised RCA: наш netplan+networkd поверх provider's expected ifupdown stack ломал их auto-recovery когда DHCP-binding разорвался на их стороне. Fix: `systemctl mask netplan systemd-networkd` (на running system, без stop — IP и SSH сохранились), Rusonyx ребутнули + положили чистый `/etc/network/interfaces.d/ifcfg-eth0` с /18 netmask через свой `start/ipadd` procedure. Все 24 docker контейнера up. Disk after GC: 79% (132G→118G/158G). Anti-pattern закреплён: НЕ использовать netplan на Rusonyx VDS. Wiki updated с revised RCA + permanent-fix runbook + 2 quirks (#9 /18 layout, #10 ifupdown vs netplan)._ _Updated: 2026-05-27 — `modulair-rag-vds-redeploy` 🟢 **closed** в ту же сессию: 4-контейнерный стек развёрнут на VDS (Portainer stack 15), acceptance 6/6. Образы пересобраны на самом VDS (push 3.36GB через traefik с дома падал 499); env/entrypoint/minio-host скорректированы под VDS-реальность. 3 follow-up'а переданы в modulair-rag handoff._ _Updated: 2026-05-27 — заведена `modulair-rag-vds-redeploy` ⚪ (handoff из modulair-rag session). NAS-loss redeploy 4 контейнеров на VDS. Блокер MinIO снят — verified up на VDS 2026-05-27. postgres `proxy`-network reachability подтверждён (`postgres:5432` резолвится из pipeline/mcp). Спека: modulair-rag concept `nas-loss-vds-redeploy-context` + compose.yml as-is._ @@ -18,6 +19,17 @@ _Updated: 2026-05-26 — заведена `bookva-tenant-cutover-prep` ⚪ (7-st _Updated: 2026-05-25 (`iis-migration-to-ruvds` 🟢 closed Phase 1 per user decision — 9/24 hostnames live на RUVDS, source IIS оставлен running. `migrate-elasticsearch-to-books-vds` 🟢 closed ранее сегодня. 16 IIS hostnames + LE renewal pipeline + decommission — descoped в Closure note, не отдельные tracker tasks.)_ +## ⚪ [restore-elasticsearch-indices-books-vds] — books VDS ES (`elasticsearch.kzntsv.site`, Portainer stack 33) пуст, slovo поиск товаров+EPZ сломан в prod + +**Status:** ready (urgent — user-facing prod outage) +**Where I stopped:** (not started — created 2026-05-28 ~16:00 MSK after prod incident diagnosis) +**Next action:** см. [restore-elasticsearch-indices-books-vds.md](restore-elasticsearch-indices-books-vds.md). Start with Portainer stack 33 audit log + `docker volume inspect /usr/docker/elasticsearch/data` (forensics) → check `_snapshot/kreknin/_all` для post-25.05 snapshots с непустыми индексами → выбрать между snapshot restore и reindex repeat (playbook реюз из `migrate-elasticsearch-to-books-vds.md`). +**Blocker:** — +**Branch:** n/a + + +--- + ## 🟢 [modulair-rag-vds-redeploy] — closed 2026-05-27 — 4-контейнерный стек развёрнут на VDS, acceptance 6/6 NAS помер → 4 контейнера пропали → fresh redeploy на VDS (89.253.255.94). Portainer stack id=15. **Acceptance 6/6 green:** 4 контейнера up без restart-loop; lightrag Uvicorn :9621; `https://modulair-mcp.kzntsv.site`→200; pipeline+tier1 0% CPU; pipeline-лог без postgres/minio ошибок. diff --git a/.tasks/restore-elasticsearch-indices-books-vds.md b/.tasks/restore-elasticsearch-indices-books-vds.md new file mode 100644 index 0000000..2a0f1b5 --- /dev/null +++ b/.tasks/restore-elasticsearch-indices-books-vds.md @@ -0,0 +1,82 @@ +# restore-elasticsearch-indices-books-vds + +## Goal + +Восстановить 3 ES индекса (`epz`, `products`, `artmone`) на canonical endpoint `elasticsearch.kzntsv.site` (books VDS, Portainer stack 33). Сейчас target ES пустой → весь поиск в books-app (slovo) сломан (404 `index_not_found_exception` для `epz` и `products`). + +## Симптомы (зафиксировано 2026-05-28 ~15:50 MSK) + +- `bookva.kzntsv.site/api/products/search?q=...` → 500 `no such index [products]`. +- `bookva.kzntsv.site/api/epz/search?q=...` → 500 `no such index [epz]`. +- `books-api` + `books-web` логи (stderr) — десятки `ResponseError: index_not_found_exception` за час. +- User-facing impact: страница `/epz/search` и поиск товаров в slovo UI не работают. + +## Текущее состояние ES endpoint'ов + +**Source (Windows host, rollback — не выключен):** `https://elasticold.kzntsv.site/` + +``` +index health docs.count store.size +artmone yellow 2621 1.4mb +epz yellow 820604 699.7mb +products yellow 105922 26.6mb +``` + +Проверено `curl -u books: https://elasticold.kzntsv.site/_cat/indices`. + +**Target (books VDS, Portainer stack 33, canonical):** `https://elasticsearch.kzntsv.site/` + +``` +_cluster/health: status=green, active_primary_shards=0, docs=0 +_cat/indices: (пусто, ни одного индекса) +_snapshot/_all: kreknin fs repo зарегистрирован (location=/snapshots) +``` + +ES жив, отвечает 200 на _cluster/health, basicAuth работает. Но **индексов нет вообще** — даже placeholder `read_me` из 25.05 исчез. Значит volume был стёрт ИЛИ контейнер recreate'нут с пустым томом между 25.05 (migration complete, smoke green) и 28.05. + +## Когда сломалось + +- **2026-05-25:** [`migrate-elasticsearch-to-books-vds`](migrate-elasticsearch-to-books-vds.md) closed. Все 3 индекса reindex'нуты с elasticold на books VDS, consumer configs sed'd `elasticold → elasticsearch`, smoke green. +- **2026-05-27 10:24 MSK:** books-api / books-web рестартовали (текущий uptime 29h). Это **до** появления ошибок — значит ES опустел уже **после** рестарта, иначе они бы залогировали 404 сразу. +- **2026-05-28 13:59 MSK** (по UTC в логах) — самая ранняя зафиксированная ошибка `no such index [epz]`. Окно поломки: 27.05 10:24 → 28.05 13:59. +- В этом окне на books VDS происходила работа `bookva-tenant-cutover-prep` (Step 2 — 9 Portainer stacks created, в т.ч. **bookva-es=37**). Возможная гипотеза — конфликт volume mount'а или случайный delete на slovo ES при подготовке bookva ES. Точная причина — детектить надо на VDS (Portainer audit log + volume listing + container restart history). + +## Pointers + +- **Migration task** (canonical процедура reindex-from-remote с elasticold на books VDS): [migrate-elasticsearch-to-books-vds.md](migrate-elasticsearch-to-books-vds.md) — playbook применим повторно как есть. +- **Frozen mappings/settings**: `.scratch/source-mappings.json` + `.scratch/source-settings.json` (от 2026-05-25, source структура не менялась — проверить на свежесть до reindex). +- **Snapshot repo** на books VDS: `kreknin` (`/snapshots`). Snapshot `pre-migration-2026-05-25` содержал только `read_me` placeholder — **не годится для восстановления** (предмиграционный, до reindex). Полезным может быть kreknin daily snapshot **после** 25.05 если он сохранил полные индексы. +- **Consumer configs:** уже указывают на `elasticsearch.kzntsv.site` (sed 25.05). После восстановления — никаких config changes, только рестарт consumers (на случай stale connection pool). + +## Acceptance + +- `curl -u books: https://elasticsearch.kzntsv.site/_cat/indices` показывает 3 индекса (`epz`/`products`/`artmone`) с doc counts ≈ source: 820604 / 105922 / 2621 (±несколько на дельту со source). +- `books-api` + `books-web` stderr за 5 минут после рестарта — 0 строк `index_not_found_exception`. +- Smoke: `https://bookva.kzntsv.site/api/epz/search?q=пушкин&...` → 200 с непустым `rows`. +- Source `elasticold.kzntsv.site` остаётся live (rollback policy не меняется, как было при оригинальной миграции). + +## Подходы (выбрать на месте) + +1. **Reindex повторно** — точно та же процедура что 25.05 (см. migrate-elasticsearch-to-books-vds.md Steps 4–6). 730MB, ~5-10 мин. Source доступен и полный. +2. **Snapshot restore** — если в `kreknin` repo есть свежий snapshot (после 25.05) с непустым `epz`/`products`/`artmone`. Проверить `_snapshot/kreknin/_all?verbose=true`. Быстрее reindex'а, если есть. +3. **Volume forensics** — параллельно (или до восстановления) посмотреть Portainer stack 33 history + `docker volume inspect /usr/docker/elasticsearch/data` + audit log в Portainer когда менялся stack. Цель — понять что произошло, чтобы оно не повторилось после bookva cutover. + +Recommendation: начать с (3) для understanding root cause, дальше (2) если snapshot есть, иначе (1). + +## Branch + +n/a (admin ops) + +## Status + +ready + +## Where I stopped + +(not started — created 2026-05-28 ~16:00 MSK by vitya@books session после диагностики prod-инцидента) + +## Next action + +См. секцию «Подходы» — старт с volume forensics (Portainer stack 33 history + docker volume inspect), параллельно проверить `_snapshot/kreknin/_all` на наличие post-25.05 snapshot'ов с непустыми индексами. Дальше выбрать между snapshot restore и reindex repeat. Восстановить → smoke от `bookva.kzntsv.site/api/epz/search`. + +