Przywracanie z Tenax¶
Każde przywracanie jest zasobem Restore. Tworzą go konsola, CLI i API. Przywracanie nigdy nie zapisuje do
istniejącej bazy danych, chyba że poprosisz o tryb w miejscu i wpiszesz nazwę celu. Wybierz tryb:
| Potrzeba | Tryb | Rola |
|---|---|---|
| Przejrzeć dane, sprawdzić poprawkę, wygenerować raport | piaskownica (domyślnie) | operator |
| Odzyskać jedną tabelę lub kilka wierszy | piaskownica, potem skopiuj to, czego potrzebujesz | operator |
| Kopia obok produkcji (nowa nazwa bazy danych) | new | restorer |
| Plik zrzutu dla kogoś spoza klastra | download (presigned URL, 1 h) | restorer |
| Wycofać cały cel | w miejscu (po kopii bezpieczeństwa) | restorer-admin |
1. Znajdź punkt¶
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
W konsoli otwórz cel, a następnie Zmiany. Każdy wiersz segmentu ma linki „piaskownica przed” i „piaskownica po”, które uzupełniają czas.
Z PITR działa każda sekunda w oknie (UTC, RFC3339): --at 2026-01-02T03:04:05Z. Bez PITR wybierz ID kopii
zapasowej: --at 20260102T020000Z-1a2b3c. Jeśli czasu nie da się przywrócić, Tenax podaje powód i wypisuje okna.
2. Przywróć do piaskownicy (bezpiecznie, domyślnie)¶
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
- Piaskownica dostaje własny namespace
tenax-sbx-<name>, losowe dane uwierzytelniające i TTL (domyślnie 24 h, przedłużenie przeztenax sandbox extend <sandbox> --by 24h, do maksimum z polityki). - Konsola zapytań jest domyślnie tylko do odczytu, z limitem czasu 30 s i limitem 1000 wierszy. Kolumny pasujące do
wzorców
maskcelu są maskowane. Każde zapytanie jest rejestrowane w audycie. - Z innego poda: nadaj mu etykietę
tenax.run/sandbox-client: <sandbox>i połącz się z adresem w klastrze, który wypisujesandbox show. - Z laptopa, gdy piaskownica została utworzona z
--expose:tenax sandbox connect <sandbox> --port 15432. Otwiera to tunel przez Cloudflare Access i wypisuje connection string. - Po zakończeniu
tenax sandbox delete <sandbox>. Wygasłe piaskownice są usuwane automatycznie.
3. Przywróć do nowej bazy danych¶
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 najpierw przywraca do piaskownicy pośredniej, uruchamia sprawdzenia, a następnie kopiuje wynik do nowej bazy
danych logicznym zrzutem i wczytaniem (ADR 0007). Nigdy nie nadpisuje istniejącej bazy danych. Secret administratora
(prefiks tenax-) znajduje się w namespace celu i wymaga CREATE DATABASE.
4. Pobranie¶
--wait wypisuje presigned URL do odszyfrowanego, ponownie skompresowanego zrzutu. Jest ważny przez 1 godzinę. URL
jest sekretem: udostępniaj go jak sekret.
5. W miejscu (ostateczność)¶
tenax restore team/app --at 2026-01-02T03:04:05Z --to in-place --confirm app --credentials-secret tenax-admin --wait
- Najpierw zatrzymaj zapisujących. Tenax nie zatrzymuje aplikacji. Przeskaluj je w dół lub przełącz w tryb konserwacji.
- Tenax wykonuje kopię bezpieczeństwa bieżącego stanu (powód
safety). Pominięcie jej wymaga--skip-safety-backup. - Przywraca do piaskownicy pośredniej, sprawdza wynik, a następnie zastępuje bazy danych celu.
- Uruchom ponownie aplikacje i sprawdź je.
Jeśli coś pójdzie nie tak, kopia bezpieczeństwa jest zwykłą wersją celu: przywróć ją w ten sam sposób.
Bez CLI¶
API to zasób Restore:
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 pokazuje postęp: plan, pobieranie kopii bazowej, odtwarzanie,
sprawdzanie, Succeeded.
Gdy sam Tenax nie działa¶
Magazyn jest źródłem prawdy, a format kopii zapasowych jest prosty:
- manifest.json wymienia każdy obiekt wraz z jego rozmiarem i SHA-256.
- Obiekty są skompresowane przez zstd i zaszyfrowane przez age: age -d -i key.txt obj.zst.age | zstd -d.
- Fizyczne kopie zapasowe Postgres to strumienie tar z pg_basebackup plus segmenty WAL.
- Logiczne kopie zapasowe Postgres to pliki pg_dump -Fc, po jednym na bazę danych.
- Kopie zapasowe MySQL to wynik mysqldump plus pliki binlogu.
Po utracie lub odbudowie klastra¶
Odzyskiwanie jest automatyczne. Tenax nie ma własnej bazy danych: magazyn przechowuje każdą kopię zapasową (i jest jedyną kopią, która się liczy), Git przechowuje BackupStore, polityki i cele (GitOps), a tożsamości age to sekrety, które przywracasz jak każde inne. Zainstaluj Tenax w nowym klastrze z tym samym magazynem i tymi samymi tożsamościami i zastosuj te same cele. Następnie:
- Kontroler sprawdza każdy magazyn przy starcie (
BackupStore.status.lastImportTime). Dla każdego celu odtwarza obiekty Backup dlakeepBackupObjectsnajnowszych kopii zapasowych (domyślnie 20), łącznie z przypiętymi. W magazynie nic nie jest zapisywane. Starsze kopie zapasowe pozostają w magazynie, objęte retencją, i w katalogu konsoli. - Przywracanie, okna PITR i konsola działają jak wcześniej. Streamer rozpoczyna nowy łańcuch od świeżej pełnej kopii zapasowej.
Import uruchamia się też przy zmianie celów i co controller.autoImport.interval (1 h). Wyłącz go przez
controller.autoImport.enabled: false. tenax catalog import [--dry-run] robi to samo ręcznie, używając Twojego
kubeconfig.