Przejdź do treści

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 przez tenax 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 mask celu 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 wypisuje sandbox 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

tenax restore team/app --at <backup-id> --to download --wait

--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
  1. Najpierw zatrzymaj zapisujących. Tenax nie zatrzymuje aplikacji. Przeskaluj je w dół lub przełącz w tryb konserwacji.
  2. Tenax wykonuje kopię bezpieczeństwa bieżącego stanu (powód safety). Pominięcie jej wymaga --skip-safety-backup.
  3. Przywraca do piaskownicy pośredniej, sprawdza wynik, a następnie zastępuje bazy danych celu.
  4. 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:

  1. Kontroler sprawdza każdy magazyn przy starcie (BackupStore.status.lastImportTime). Dla każdego celu odtwarza obiekty Backup dla keepBackupObjects najnowszych 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.
  2. 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.