So funktioniert Tenax¶
Tenax ist ein Kubernetes-Operator. Sie deklarieren, wohin Backups gehen, wie oft und wie lange, und welche Datenbanken; den Rest übernimmt Tenax.
flowchart LR
subgraph Declared["Declared in git"]
S[BackupStore<br/>bucket + keys]
P[BackupPolicy<br/>schedule, retention, window]
T[BackupTarget<br/>one database]
end
subgraph Created["Created by Tenax or by you"]
B[Backup<br/>one full backup]
R[Restore<br/>to a sandbox, new DB, download, in place]
X[Sandbox<br/>a throwaway database]
end
T --> P --> S
T -. schedule .-> B
R -. sandbox .-> X
| Ressource | Geltungsbereich | Wer sie anlegt | Was sie ist |
|---|---|---|---|
BackupStore |
Cluster | Sie | Ein S3-Bucket, seine Zugangsdaten und die age-Empfänger, für die jedes Objekt verschlüsselt wird. |
BackupPolicy |
Namespace | Sie (oder die Presets des Charts) | Zeitplan, Point-in-Time-Fenster, Aufbewahrungsstufen, Limits, Lastschutz, Prüfung, Komprimierung. |
BackupTarget |
Namespace, neben der Datenbank | Sie | Ein Datenbankserver: Engine, Endpunkt, Zugangsdaten, Policy, Checks, Masken. |
Backup |
Namespace des Ziels | Tenax (Zeitplan, Sofort-Backup, Neustart der Kette) | Ein Lauf einer Vollsicherung. Nur die letzten paar bleiben als Objekte erhalten; S3 enthält alle. |
Restore |
Namespace des Ziels | Sie, die Konsole oder die CLI | Ein Plan von einem Zeitpunkt oder einer Backup-ID zu einem Ziel. |
Sandbox |
Cluster | ein Restore in eine Sandbox |
Eine private Datenbank mit TTL, Zugangsdaten und Abfragekonsole. |
Der Datenpfad¶
flowchart LR
db[(Postgres / MySQL)] -->|pg_basebackup, pg_dump, mysqldump| mover[mover Job]
db -->|WAL receiver, mysqlbinlog| streamer[streamer]
mover --> pipe[zstd → age → SHA-256 → parallel multipart]
streamer --> pipe
pipe --> s3[(S3 bucket<br/>manifest.json written last)]
s3 --> restorer[restorer Job<br/>verify → decrypt → replay → checks]
restorer --> dest[sandbox · new database · in place · download]
- Der Controller plant nur. Mover und Restorer sind Jobs; jedes Ziel mit Point-in-Time-Recovery hat ein Streamer-Deployment. Bytes laufen nie durch den Controller oder die API.
- Nichts hängt. Keine Mounts, kein iSCSI, kein FUSE, keine Blockgeräte; Datenbanken werden nur über das Netzwerk erreicht. Jeder I/O-Aufruf hat eine Deadline, jeder Stream einen Fortschritts-Watchdog, und Kindprozesse laufen in ihrer eigenen Prozessgruppe, damit sie mit ihr beendet werden.
- Crash-only. Jeder Pod kann jederzeit beendet werden. Der Zustand liegt in CRDs und S3, und ein Backup existiert erst, wenn sein Manifest als Letztes geschrieben ist; ein halb geschriebenes Backup wird daher nie für ein vollständiges gehalten.
Katalog und Konsole¶
tenax-api listet beim Start die Manifeste in jedem Store auf und hält einen Index im Speicher: Ziele, Backups,
Änderungssegmente und Point-in-Time-Fenster. Inventare und maskierte Vorschauen werden zusätzlich für einen
Katalog-Schlüssel verschlüsselt, der sie lesen, aber keine Dumps oder WAL entschlüsseln kann
(ADR 0009). Der Cache ist entbehrlich; S3 ist die maßgebliche Quelle.