コンテンツにスキップ

Tenax で復元する

すべての復元は Restore リソースです。コンソール、CLI、API のいずれもこれを作成します。インプレース を指定して ターゲット名を入力しない限り、復元が既存のデータベースに書き込むことはありません。モードを選びます。

目的 モード ロール
データを見る、修正を確認する、レポートを実行する サンドボックス (デフォルト) operator
テーブルひとつや数行を取り戻す サンドボックスに復元し、必要なものをコピー operator
本番の隣にコピーを作る (新しいデータベース名) new restorer
クラスター外の人にダンプファイルを渡す ダウンロード (署名付き URL、1 時間) restorer
ターゲット全体を巻き戻す インプレース (安全のためのバックアップの後) restorer-admin

1. 時点を見つける

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

コンソールではターゲットを開き、変更 を開きます。各セグメントの行には「sandbox before」と「sandbox after」の リンクがあり、時刻が自動で入力されます。

PITR があれば、ウィンドウ内の任意の 1 秒を指定できます (UTC、RFC3339): --at 2026-01-02T03:04:05Z。PITR がなければ バックアップ ID を選びます: --at 20260102T020000Z-1a2b3c。指定した時刻が復元できない場合、Tenax はその理由を示し、 ウィンドウを表示します。

2. サンドボックスに復元する (安全、デフォルト)

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
  • サンドボックスには専用の Namespace tenax-sbx-<name>、ランダムな認証情報、TTL が与えられます (デフォルト 24 時間。 tenax sandbox extend <sandbox> --by 24h でポリシーの上限まで延長できます)。
  • クエリコンソールはデフォルトで読み取り専用で、タイムアウトは 30 秒、上限は 1,000 行です。ターゲットの mask パターンに 一致する列はマスクされます。すべてのクエリは監査されます。
  • 別の Pod から: その Pod に tenax.run/sandbox-client: <sandbox> ラベルを付け、sandbox show が表示する クラスター内アドレスに接続します。
  • ノート PC から (サンドボックスが --expose 付きで作成された場合): tenax sandbox connect <sandbox> --port 15432。Cloudflare Access 経由のトンネルを開き、接続文字列を表示します。
  • 終わったら tenax sandbox delete <sandbox>。期限切れのサンドボックスは自動的に削除されます。

3. 新しいデータベースに復元する

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 はまずステージング用のサンドボックスに復元してチェックを実行し、その結果を論理ダンプとロードで新しいデータベースに コピーします (ADR 0007)。既存のデータベースを上書きすることはありません。管理者用 Secret (tenax- プレフィックス) は ターゲットの Namespace に置き、CREATE DATABASE 権限が必要です。

4. ダウンロード

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

--wait は、復号して再圧縮したダンプへの署名付き URL を表示します。有効期間は 1 時間です。URL はシークレットなので、 シークレットとして扱って共有してください。

5. インプレース (最後の手段)

tenax restore team/app --at 2026-01-02T03:04:05Z --to in-place --confirm app --credentials-secret tenax-admin --wait
  1. まず書き込み元を止めます。 Tenax はアプリケーションを停止しません。スケールダウンするか、メンテナンスモードにします。
  2. Tenax は現在の状態の安全のためのバックアップを取ります (理由は safety)。省略するには --skip-safety-backup が必要です。
  3. ステージング用のサンドボックスに復元して結果をチェックし、ターゲットのデータベースを置き換えます。
  4. アプリケーションを再開し、動作を確認します。

何か問題があっても、安全のためのバックアップはターゲットの通常のバージョンなので、同じ方法で復元できます。

CLI を使わない場合

Restore リソースそのものが 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 で進捗が表示されます: 計画、ベースの取得、リプレイ、チェック、 Succeeded。

Tenax 自体が停止しているとき

信頼できる唯一の情報源はストアであり、バックアップ形式は単純です。 - manifest.json はすべてのオブジェクトをサイズと SHA-256 付きで列挙します。 - オブジェクトは zstd で圧縮され、age で暗号化されています: age -d -i key.txt obj.zst.age | zstd -d。 - Postgres の物理バックアップは pg_basebackup の tar ストリームと WAL セグメントです。 - Postgres の論理バックアップは pg_dump -Fc ファイルで、データベースごとにひとつです。 - MySQL のバックアップは mysqldump の出力と binlog ファイルです。

クラスターが失われた、または再構築された後

復旧は自動です。Tenax は独自のデータベースを持ちません。ストアがすべてのバックアップを保持し (重要なのはこのコピーだけです)、 Git が BackupStore、ポリシー、ターゲットを保持し (GitOps)、age のアイデンティティは他の Secret と同じように復元する シークレットです。新しいクラスターに同じストアと同じアイデンティティで Tenax をインストールし、同じターゲットを適用します。その後:

  1. コントローラーは起動時に各ストアを確認します (BackupStore.status.lastImportTime)。ターゲットごとに、最新の keepBackupObjects 件 (デフォルト 20) のバックアップの Backup オブジェクトを、ピンを含めて再作成します。ストアには何も 書き込みません。それより古いバックアップはストアに残り、保持ポリシーの対象となり、コンソールのカタログにも表示されます。
  2. 復元、PITR ウィンドウ、コンソールは以前と同じように動きます。ストリーマーは新しいフルバックアップから新しいチェーンを開始します。

インポートはターゲットが変わったときと、controller.autoImport.interval (1 時間) ごとにも実行されます。 controller.autoImport.enabled: false で無効にできます。tenax catalog import [--dry-run] は同じことを手動で、 あなたの kubeconfig を使って行います。