From 2930842e3fb5d1e4a67b94b70f7a1ff378008a49 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Tue, 23 Jun 2026 09:38:09 +0300 Subject: [PATCH] Backups: update ADR after migration --- ...06-22-restic-intelligent-tiering-phases.md | 54 ++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/docs/adr/ADR-2026-06-22-restic-intelligent-tiering-phases.md b/docs/adr/ADR-2026-06-22-restic-intelligent-tiering-phases.md index 821542b..d5b6b49 100644 --- a/docs/adr/ADR-2026-06-22-restic-intelligent-tiering-phases.md +++ b/docs/adr/ADR-2026-06-22-restic-intelligent-tiering-phases.md @@ -33,9 +33,11 @@ restic не годится — это churn, эквивалентный репа вручную или заводить такое управление. Идентификатор класса подтверждён доками — `INTELLIGENT_TIERING` (Yandex -поддерживает STANDARD, COLD, ICE, INTELLIGENT_TIERING). Остаётся -неподтверждённым только min-retention / штраф за раннее удаление архивного -уровня внутри IT. +поддерживает STANDARD, COLD, ICE, INTELLIGENT_TIERING). Явный min-retention +(12 месяцев со штрафом за раннее удаление) документирован **только для +класса ICE**; для архивного уровня внутри IT такого минимума в доках нет — +значит transition и последующий `prune` для IT низкорисковы. Финальная +проверка — по биллингу после первой реальной миграции. ## Рассмотренные варианты @@ -55,12 +57,15 @@ restic не годится — это churn, эквивалентный репа пакет ставится из apt (`python3-croniter`) тем же механизмом, что и остальное, а гибкость реальная — поменять «раз в квартал» на «раз в месяц» = правка одной строки конфига. -- **Storage class сейчас: Вариант A** (`-o s3.storage-class=INTELLIGENT_TIERING` - в restic) **vs Вариант B** (lifecycle-правило / copy-in-place на бакете) - **vs отложить.** A влияет только на новые объекты — уже лежащие бэкапы в - STANDARD так и останутся; B переводит существующие данные, но требует - завести управление бакетом, которого в проекте нет. **Выбрано отложить** - до подтверждения min-retention архивного уровня IT. +- **Перевод существующих данных в IT: copy-in-place vs lifecycle vs + отложить.** Lifecycle в Yandex переводит только «на более холодный» + (STANDARD→COLD→ICE), переход именно в IT им не заявлен — отпал. + Перезаливка объектов для restic не годится (churn ≈ репак). Остаётся + **copy-in-place** (`aws s3 cp --recursive --storage-class + INTELLIGENT_TIERING`, серверная копия «на себя»). **Выбран copy-in-place** + — после того как доки сняли блокер по min-retention. Для будущих записей + отдельно — флип класса бакета по умолчанию на IT (вариант A с + `-o s3.storage-class` в коде не понадобился). ## Решение @@ -80,12 +85,21 @@ restic не годится — это churn, эквивалентный репа `prune` тюнингован под IT (`--max-unused 20%`, `--max-repack-size 5G`): чем меньше холодных паков переписываем, тем дольше держится охлаждение. -Storage class IT и lifecycle на бакете **намеренно отложены**: пока не -подтверждён min-retention архивного уровня IT, transition существующих -данных рискован (возможен штраф за раннее удаление при последующем prune). -Сама миграция уже лежащих бэкапов делается lifecycle-правилом или -copy-in-place с `--storage-class INTELLIGENT_TIERING`, а не сменой -дефолтного класса бакета (та сработает только для новых объектов). +Перевод бакетов в IT идёт двумя действиями на каждый бакет: смена класса +**по умолчанию** на IT в консоли (будущие записи restic) + разовая +**copy-in-place** существующих объектов (`aws s3 cp s3:/// +s3:/// --recursive --storage-class INTELLIGENT_TIERING +--metadata-directive COPY`). Класс отдаётся прямо в листинге +(`list-objects-v2 --query 'Contents[].[StorageClass,Key]'`) — им и +проверяем. Грабли: для проверки нельзя `--max-items 1` (клиентская +пагинация aws-cli дописывает в вывод токен `None`) — нужен серверный +`--max-keys`. + +Статус миграции: **`rivendell` переведён 2026-06-23** (дефолт бакета = IT +со скриншота, все объекты `config`/`data/` показывают +`INTELLIGENT_TIERING`). `eos` (основная экономия) и `buckland` — следующими, +после нескольких дней наблюдения за биллингом `rivendell`. + Retention оставлен прежним (`--keep-daily 90 --keep-monthly 36`) — это решение про охлаждение и частоту операций, а не про глубину истории. @@ -102,6 +116,10 @@ Retention оставлен прежним (`--keep-daily 90 --keep-monthly 36`) - `-` Подвох croniter: при суточном триггере поля минут/часов в выражениях декоративны (держим `* *`) — фаза идёт в момент ночного прогона, а не во время из выражения. -- Осталось сделать: подтвердить min-retention / штраф за раннее удаление - архивного уровня IT, затем перевести существующие бэкапы со STANDARD на - `INTELLIGENT_TIERING` через lifecycle-правило или copy-in-place. +- `+` Миграция существующих объектов — разовая copy-in-place, без репака + restic: содержимое и ключи паков не меняются, restic остаётся рабочим. +- `-` После перевода объекты стартуют на уровне FREQUENT и охлаждаются + ~120 дней — полка экономии устанавливается не сразу. +- Осталось сделать: несколько дней последить за биллингом и бэкапами + `rivendell` (убедиться, что за transition нет штрафа), затем повторить + пару «флип дефолта + copy-in-place» для `eos` и `buckland`.