Memulihkan dengan Tenax¶
Setiap pemulihan adalah resource Restore. Konsol, CLI, dan API semuanya membuat resource ini. Pemulihan tidak pernah
menulis ke basis data yang sudah ada kecuali Anda meminta di tempat dan mengetik nama target. Pilih modenya:
| Kebutuhan | Mode | Peran |
|---|---|---|
| Melihat data, memeriksa perbaikan, menjalankan laporan | sandbox (bawaan) | operator |
| Mengembalikan satu tabel atau beberapa baris | sandbox, lalu salin yang Anda perlukan | operator |
| Salinan di samping produksi (nama basis data baru) | new | restorer |
| Berkas dump untuk seseorang di luar klaster | download (URL presigned, 1 jam) | restorer |
| Mengembalikan seluruh target ke kondisi sebelumnya | in place (setelah cadangan pengaman) | restorer-admin |
1. Temukan titiknya¶
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
Di konsol, buka target, lalu Perubahan. Setiap baris segmen memiliki tautan "sandbox sebelum" dan "sandbox sesudah" yang mengisi waktunya secara otomatis.
Dengan PITR, detik mana pun di dalam jendela dapat dipakai (UTC, RFC3339): --at 2026-01-02T03:04:05Z. Tanpa PITR,
pilih id cadangan: --at 20260102T020000Z-1a2b3c. Jika waktunya tidak dapat dipulihkan, Tenax menjelaskan alasannya
dan mencetak jendela-jendelanya.
2. Pulihkan ke sandbox (aman, pilihan bawaan)¶
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
- Sandbox mendapat namespace sendiri
tenax-sbx-<name>, kredensial acak, dan TTL (bawaan 24 jam, perpanjang dengantenax sandbox extend <sandbox> --by 24h, hingga maksimum kebijakan). - Konsol kueri bersifat baca-saja secara bawaan, dengan timeout 30 detik dan batas 1.000 baris. Kolom yang cocok
dengan pola
maskmilik target disamarkan. Setiap kueri diaudit. - Dari pod lain: beri pod tersebut label
tenax.run/sandbox-client: <sandbox>lalu hubungkan ke alamat dalam klaster yang dicetak olehsandbox show. - Dari laptop, jika sandbox dibuat dengan
--expose:tenax sandbox connect <sandbox> --port 15432. Perintah ini membuka tunnel melalui Cloudflare Access dan mencetak string koneksi. tenax sandbox delete <sandbox>setelah selesai. Sandbox yang kedaluwarsa dihapus secara otomatis.
3. Pulihkan ke basis data baru¶
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 lebih dulu memulihkan ke sandbox staging, menjalankan pemeriksaan, lalu menyalin hasilnya ke basis data baru
dengan dump dan load logis (ADR 0007). Tenax tidak pernah menimpa basis data yang sudah ada. Secret admin (prefiks
tenax-) berada di namespace target dan memerlukan CREATE DATABASE.
4. Unduhan¶
--wait mencetak URL presigned ke dump yang sudah didekripsi dan dikompresi ulang. URL ini berlaku selama 1 jam. URL
tersebut adalah rahasia: bagikan selayaknya rahasia.
5. Di tempat (pilihan terakhir)¶
tenax restore team/app --at 2026-01-02T03:04:05Z --to in-place --confirm app --credentials-secret tenax-admin --wait
- Hentikan penulis lebih dulu. Tenax tidak menghentikan aplikasi. Kurangi skalanya, atau masukkan ke mode pemeliharaan.
- Tenax membuat cadangan pengaman dari kondisi saat ini (alasan
safety). Untuk melewatinya diperlukan--skip-safety-backup. - Tenax memulihkan ke sandbox staging, memeriksa hasilnya, lalu mengganti basis data target.
- Jalankan kembali aplikasi dan periksa.
Jika ada yang salah, cadangan pengaman adalah versi biasa dari target: pulihkan dengan cara yang sama.
Tanpa CLI¶
Resource Restore adalah API-nya:
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 menampilkan kemajuannya: plan, fetching base, replaying, checking,
Succeeded.
Saat Tenax sendiri sedang mati¶
Store adalah sumber kebenaran, dan format cadangannya sederhana:
- manifest.json mencantumkan setiap objek beserta ukuran dan SHA-256-nya.
- Objek dikompresi dengan zstd dan dienkripsi dengan age: age -d -i key.txt obj.zst.age | zstd -d.
- Cadangan fisik Postgres berupa aliran tar pg_basebackup ditambah segmen WAL.
- Cadangan logis Postgres berupa berkas pg_dump -Fc, satu per basis data.
- Cadangan MySQL berupa keluaran mysqldump ditambah berkas binlog.
Setelah klaster hilang atau dibangun ulang¶
Pemulihannya otomatis. Tenax tidak menyimpan basis data sendiri: store menyimpan setiap cadangan (dan merupakan satu-satunya salinan yang penting), Git menyimpan BackupStore, kebijakan, dan target (GitOps), dan identitas age adalah secret yang Anda pulihkan seperti secret lainnya. Pasang Tenax di klaster baru dengan store dan identitas yang sama, lalu terapkan target yang sama. Kemudian:
- Controller memeriksa setiap store saat mulai (
BackupStore.status.lastImportTime). Untuk setiap target, controller membuat ulang objek Backup darikeepBackupObjectscadangan terbaru (bawaan 20), termasuk yang disematkan. Tidak ada yang ditulis ke store. Cadangan yang lebih lama tetap ada di store, di bawah retensi, dan di katalog konsol. - Pemulihan, jendela PITR, dan konsol bekerja seperti sebelumnya. Streamer memulai rantai baru dari cadangan penuh yang baru.
Impor juga berjalan saat target berubah dan setiap controller.autoImport.interval (1 jam). Matikan dengan
controller.autoImport.enabled: false. tenax catalog import [--dry-run] melakukan hal yang sama secara manual,
memakai kubeconfig Anda.