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 mittenax 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, diesandbox showausgibt. - Vom Laptop, wenn die Sandbox mit
--exposeangelegt 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¶
--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
- Stoppen Sie zuerst die Schreiber. Tenax hält keine Anwendungen an. Skalieren Sie sie herunter oder versetzen Sie sie in den Wartungsmodus.
- Tenax erstellt ein Sicherheits-Backup des aktuellen Zustands (Grund
safety). Um es zu überspringen, braucht es--skip-safety-backup. - Es stellt in eine Staging-Sandbox wieder her, prüft das Ergebnis und ersetzt dann die Datenbanken des Ziels.
- 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:
- Der Controller prüft beim Start jeden Store (
BackupStore.status.lastImportTime). Für jedes Ziel legt er die Backup-Objekte der neuestenkeepBackupObjectsBackups (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. - 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.