Восстановление с Tenax¶
Каждое восстановление — это ресурс Restore. Его создают и консоль, и CLI, и API. Восстановление никогда не пишет в
существующую базу данных, если только вы не выбрали на месте и не ввели имя цели. Выберите режим:
| Задача | Режим | Роль |
|---|---|---|
| Посмотреть данные, проверить исправление, сделать отчёт | песочница (по умолчанию) | operator |
| Вернуть одну таблицу или несколько строк | песочница, затем скопировать нужное | operator |
| Копия рядом с продакшеном (новое имя базы данных) | new | restorer |
| Файл дампа для кого-то за пределами кластера | download (presigned URL, 1 ч) | restorer |
| Откатить цель целиком | in place (после страховочной резервной копии) | restorer-admin |
1. Найдите точку¶
tenax targets # PITR windows and last backups
tenax backups team/app # versions (ids, times, sizes, verified, pinned)
tenax changes team/app --since 6h # what changed when: per-table counts and DDL per segment
tenax diff <backup-a> <backup-b> # schema and row changes between two versions
В консоли откройте цель, затем Изменения. В каждой строке сегмента есть ссылки «песочница до» и «песочница после», которые подставляют время.
С PITR подходит любая секунда внутри окна (UTC, RFC3339): --at 2026-01-02T03:04:05Z. Без PITR выберите id
резервной копии: --at 20260102T020000Z-1a2b3c. Если момент нельзя восстановить, Tenax объясняет почему и выводит
окна.
2. Восстановление в песочницу (безопасно, по умолчанию)¶
tenax restore team/app --at 2026-01-02T03:04:05Z --ttl 6h --wait
tenax sandbox show <sandbox> # connection info, expiry
tenax query <sandbox> -e "select count(*) from orders where created_at > now() - interval '1 day'"
tenax query <sandbox> -e "select * from orders where id = 42" -o csv > order42.csv
- Песочница получает собственный namespace
tenax-sbx-<name>, случайные учётные данные и TTL (по умолчанию 24 ч, продлевается командойtenax sandbox extend <sandbox> --by 24hдо максимума политики). - Консоль запросов по умолчанию работает только на чтение, с тайм-аутом 30 с и лимитом 1 000 строк. Столбцы,
подходящие под шаблоны
maskцели, маскируются. Каждый запрос записывается в аудит. - Из другого пода: добавьте ему метку
tenax.run/sandbox-client: <sandbox>и подключитесь к адресу внутри кластера, который выводитsandbox show. - С ноутбука, если песочница создана с
--expose:tenax sandbox connect <sandbox> --port 15432. Команда открывает туннель через Cloudflare Access и выводит строку подключения. - Когда закончите, выполните
tenax sandbox delete <sandbox>. Истёкшие песочницы удаляются автоматически.
3. Восстановление в новую базу данных¶
tenax restore team/app --at 2026-01-02T03:04:05Z --to new \
--host postgres.team.svc --database app_restored --credentials-secret tenax-admin --wait
Сначала Tenax восстанавливает данные в промежуточную песочницу, выполняет проверки, а затем копирует результат в
новую базу данных логическим дампом и загрузкой (ADR 0007). Существующая база данных никогда не перезаписывается.
Секрет администратора (префикс tenax-) находится в namespace цели и должен иметь право CREATE DATABASE.
4. Скачивание¶
--wait выводит presigned URL на расшифрованный и заново сжатый дамп. Он действителен 1 час. URL — это секрет:
обращайтесь с ним соответственно.
5. На месте (крайняя мера)¶
tenax restore team/app --at 2026-01-02T03:04:05Z --to in-place --confirm app --credentials-secret tenax-admin --wait
- Сначала остановите тех, кто пишет. Tenax не останавливает приложения. Масштабируйте их до нуля или переведите в режим обслуживания.
- Tenax делает страховочную резервную копию текущего состояния (причина
safety). Чтобы её пропустить, нужен--skip-safety-backup. - Данные восстанавливаются в промежуточную песочницу, результат проверяется, затем базы данных цели заменяются.
- Снова запустите приложения и проверьте их.
Если что-то пошло не так, страховочная резервная копия — обычная версия цели: восстановите её тем же способом.
Без CLI¶
Ресурс Restore и есть API:
apiVersion: tenax.run/v1alpha1
kind: Restore
metadata: { name: app-incident-42, namespace: team }
spec:
target: app
source: { time: "2026-01-02T03:04:05Z" } # or backupID: ..., or latest: true
destination:
mode: sandbox
sandbox: { ttl: 6h }
kubectl -n team get restore app-incident-42 -w показывает прогресс: план, загрузка базы, применение изменений,
проверка, Succeeded.
Когда не работает сам Tenax¶
Источник истины — хранилище, а формат резервных копий простой:
- manifest.json перечисляет все объекты с их размером и SHA-256.
- Объекты сжаты zstd и зашифрованы age: age -d -i key.txt obj.zst.age | zstd -d.
- Физические резервные копии Postgres — это tar-потоки pg_basebackup плюс сегменты WAL.
- Логические резервные копии Postgres — файлы pg_dump -Fc, по одному на базу данных.
- Резервные копии MySQL — вывод mysqldump плюс файлы binlog.
После потери или пересоздания кластера¶
Восстановление происходит автоматически. У Tenax нет собственной базы данных: хранилище содержит все резервные копии (и это единственная копия, которая имеет значение), Git хранит BackupStore, политики и цели (GitOps), а идентичности age — это секреты, которые вы восстанавливаете, как любые другие. Установите Tenax в новый кластер с тем же хранилищем и теми же идентичностями и примените те же цели. Затем:
- При запуске контроллер проверяет каждое хранилище (
BackupStore.status.lastImportTime). Для каждой цели он пересоздаёт объекты Backup дляkeepBackupObjectsсамых новых резервных копий (по умолчанию 20), включая закреплённые. В хранилище ничего не записывается. Более старые копии остаются в хранилище, под политикой хранения, и в каталоге консоли. - Восстановления, окна PITR и консоль работают как прежде. Streamer начинает новую цепочку со свежей полной резервной копии.
Импорт также запускается при изменении целей и каждые controller.autoImport.interval (1 ч). Отключается он через
controller.autoImport.enabled: false. tenax catalog import [--dry-run] делает то же самое вручную, используя ваш
kubeconfig.