Zum Inhalt

Wiederherstellen mit Tenax

Jede Wiederherstellung ist eine Restore-Ressource. Konsole, CLI und API legen alle eine an. Wiederherstellungen schreiben nie in eine bestehende Datenbank, außer Sie verlangen an Ort und Stelle und tippen den Namen des Ziels ein. Wählen Sie den Modus:

Bedarf Modus Rolle
Daten ansehen, einen Fix prüfen, einen Bericht erstellen Sandbox (Standard) operator
Eine Tabelle oder ein paar Zeilen zurückholen Sandbox, dann das Benötigte kopieren operator
Eine Kopie neben der Produktion (neuer Datenbankname) neu restorer
Eine Dump-Datei für jemanden außerhalb des Clusters Download (vorsignierte URL, 1 h) restorer
Das ganze Ziel zurücksetzen an Ort und Stelle (nach einem Sicherheits-Backup) restorer-admin

1. Den Zeitpunkt finden

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

Öffnen Sie in der Konsole das Ziel und dann Änderungen. Jede Segmentzeile hat die Links „sandbox before“ und „sandbox after“, die den Zeitpunkt vorausfüllen.

Mit PITR funktioniert jede Sekunde innerhalb eines Fensters (UTC, RFC3339): --at 2026-01-02T03:04:05Z. Ohne PITR wählen Sie eine Backup-ID: --at 20260102T020000Z-1a2b3c. Ist der Zeitpunkt nicht wiederherstellbar, nennt Tenax den Grund und gibt die Fenster aus.

2. In eine Sandbox wiederherstellen (sicher, der Standard)

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
  • Die Sandbox erhält einen eigenen Namespace tenax-sbx-<name>, zufällige Zugangsdaten und eine TTL (Standard 24 h, verlängerbar mit tenax sandbox extend <sandbox> --by 24h, bis zum Maximum der Policy).
  • Die Abfragekonsole ist standardmäßig nur lesend, mit 30 s Timeout und einem Limit von 1.000 Zeilen. Spalten, die auf die mask-Muster des Ziels passen, werden maskiert. Jede Abfrage wird protokolliert.
  • Aus einem anderen Pod: Geben Sie ihm das Label tenax.run/sandbox-client: <sandbox> und verbinden Sie sich mit der clusterinternen Adresse, die sandbox show ausgibt.
  • Vom Laptop, wenn die Sandbox mit --expose angelegt wurde: tenax sandbox connect <sandbox> --port 15432. Das öffnet den Tunnel über Cloudflare Access und gibt den Connection-String aus.
  • tenax sandbox delete <sandbox>, wenn Sie fertig sind. Abgelaufene Sandboxes werden automatisch gelöscht.

3. In eine neue Datenbank wiederherstellen

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 stellt zuerst in eine Staging-Sandbox wieder her, führt die Checks aus und kopiert das Ergebnis dann per logischem Dump und Load in die neue Datenbank (ADR 0007). Eine bestehende Datenbank überschreibt es nie. Das Admin-Secret (Präfix tenax-) liegt im Namespace des Ziels und braucht CREATE DATABASE.

4. Download

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

--wait gibt eine vorsignierte URL zu einem entschlüsselten, neu komprimierten Dump aus. Sie gilt 1 Stunde. Die URL ist ein Geheimnis: Teilen Sie sie entsprechend.

5. An Ort und Stelle (letzter Ausweg)

tenax restore team/app --at 2026-01-02T03:04:05Z --to in-place --confirm app --credentials-secret tenax-admin --wait
  1. Stoppen Sie zuerst die Schreiber. Tenax hält keine Anwendungen an. Skalieren Sie sie herunter oder versetzen Sie sie in den Wartungsmodus.
  2. Tenax erstellt ein Sicherheits-Backup des aktuellen Zustands (Grund safety). Um es zu überspringen, braucht es --skip-safety-backup.
  3. Es stellt in eine Staging-Sandbox wieder her, prüft das Ergebnis und ersetzt dann die Datenbanken des Ziels.
  4. Starten Sie die Anwendungen wieder und prüfen Sie sie.

Geht etwas schief, ist das Sicherheits-Backup eine normale Version des Ziels: Stellen Sie es auf dieselbe Weise wieder her.

Ohne die CLI

Die Restore-Ressource ist die 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 zeigt den Fortschritt: Plan, Basis abrufen, Replay, Prüfen, Succeeded.

Wenn Tenax selbst ausgefallen ist

Der Store ist die maßgebliche Quelle, und das Backup-Format ist schlicht: - manifest.json listet jedes Objekt mit Größe und SHA-256. - Objekte sind mit zstd komprimiert und mit age verschlüsselt: age -d -i key.txt obj.zst.age | zstd -d. - Physische Postgres-Backups sind pg_basebackup-Tar-Streams plus WAL-Segmente. - Logische Postgres-Backups sind pg_dump -Fc-Dateien, eine pro Datenbank. - MySQL-Backups sind mysqldump-Ausgaben plus Binlog-Dateien.

Nachdem ein Cluster verloren oder neu aufgebaut wurde

Die Wiederherstellung läuft automatisch. Tenax führt keine eigene Datenbank: Der Store enthält jedes Backup (und ist die einzige Kopie, auf die es ankommt), Git enthält BackupStore, Policies und Ziele (GitOps), und die age-Identitäten sind Secrets, die Sie wie jedes andere wiederherstellen. Installieren Sie Tenax im neuen Cluster mit demselben Store und denselben Identitäten und wenden Sie dieselben Ziele an. Dann:

  1. Der Controller prüft beim Start jeden Store (BackupStore.status.lastImportTime). Für jedes Ziel legt er die Backup-Objekte der neuesten keepBackupObjects Backups (Standard 20) neu an, Pins eingeschlossen. In den Store wird nichts geschrieben. Ältere Backups bleiben im Store, unter der Aufbewahrung, und im Katalog der Konsole.
  2. Wiederherstellungen, PITR-Fenster und die Konsole funktionieren wie zuvor. Der Streamer beginnt eine neue Kette mit einer frischen Vollsicherung.

Der Import läuft auch, wenn sich Ziele ändern, und alle controller.autoImport.interval (1 h). Abschalten lässt er sich mit controller.autoImport.enabled: false. tenax catalog import [--dry-run] erledigt dasselbe von Hand, mit Ihrer Kubeconfig.