バックアップと復元ウィンドウ¶
ターゲットの履歴はチェーンです。スケジュールに沿った フルバックアップ と、その間を埋める連続した 変更ストリーム (Postgres の WAL、MySQL の binlog) から成ります。フルバックアップとその後の変更でカバーされる任意の 1 秒を復元できます。 この範囲が ポイントインタイムウィンドウ です。
gantt
dateFormat YYYY-MM-DD HH:mm
axisFormat %a %d
section Full backups
daily full :milestone, 2026-10-01 02:07, 0d
daily full :milestone, 2026-10-02 02:07, 0d
daily full :milestone, 2026-10-03 02:07, 0d
daily full :milestone, 2026-10-04 02:07, 0d
section Change stream
WAL / binlog segments :active, 2026-10-01 02:07, 2026-10-04 18:00
フルバックアップ¶
| エンジン | モード | ツール | 復元 |
|---|---|---|---|
| Postgres 15–17 | physical (デフォルト) |
レプリケーションプロトコル経由の pg_basebackup -Ft -X fetch |
ベースバックアップ + 秒単位までの WAL リプレイ |
| Postgres 15–17 | logical |
pg_dump -Fc、データベースごとに 1 オブジェクト。テーブルの除外と選択的エクスポート |
pg_restore。物理チェーンがあればそれを通じた WAL リプレイも |
| MySQL 8.4 | logical |
mysqldump --single-transaction --source-data=2 (ルーチン、イベント、トリガー) |
ロード + 秒単位までの binlog リプレイ |
すべてのバックアップは インベントリ を記録します: データベース、テーブル、列、インデックス、行数の推定値とサイズ、
そしてマイグレーションテーブルがある場合はマイグレーションのバージョンです。コンソールと tenax diff が比較するのはこれです。
変更ストリーム¶
ポイントインタイムリカバリを有効にした各ターゲットには、ストリーマー がひとつあります。
- Postgres: 物理レプリケーションスロット上で動く Tenax 独自の WAL レシーバー (ADR 0005)。 スロットにより、ストリーマーの再起動中も WAL が失われないことが保証されます。
- MySQL: 直近のフルバックアップの binlog 位置から
mysqlbinlog --read-from-remote-server --raw --stop-never。
セグメントは完成するたびにアップロードされ、書き込み中のセグメントも partialInterval (デフォルト 60 秒) ごとに
アップロードされるので、直近の 1 分も復元できます。各セグメントにはサマリーが付きます: テーブルごとのコミット、挿入、
更新、削除の件数、DDL、そしてオプションでマスク済みの行プレビューです。
ストリームが途切れた場合 (スロットが失われた、binlog がパージされた)、Tenax はチェーンを破損としてマークし、アラートを出し
(TenaxStreamChainBroken)、新しいチェーンを開始してすぐにフルバックアップを取ります (理由は chain-restart)。
古いウィンドウは途切れた時点まで引き続き復元できます。
保持¶
フルバックアップは階層ごとに保持され、セグメントはウィンドウに必要な範囲だけ保持されます。ガベージコレクションはそれ以外を すべて削除しますが、ピン留めされたものは決して削除しません。
| プリセット | ウィンドウ | 日次 | 週次 | 月次 | 年次 |
|---|---|---|---|---|---|
prod |
7 日 | 14 | 8 | 12 | 5 |
dev |
3 日 | 7 | 4 | 3 | 0 |
critical |
14 日 | 30 | 12 | 24 | 7 |
その日に最初にコミットされたフルバックアップがその日の日次、ISO 週で最初のものがその週の週次、以下同様です。ひとつの
バックアップが複数の階層を兼ねることができ、コピーは作られません。ピン (tenax pin <id> --reason …) は階層に関係なく
バックアップを保持します。GC は削除する前に計画をバケットに書き込み、データより先にマニフェストを削除し、孤立した不完全な
アップロードを 1 日後に片付けます。
ストレージ形式¶
<store prefix>/<org>/<project>/<namespace>/<target>/
full/<backup-id>/manifest.json # written last: the commit marker
full/<backup-id>/data/<database>.zst.age # dumps or the base backup tar
full/<backup-id>/inventory.json.zst.age # also readable with the catalog key
full/<backup-id>/tags.json # tiers, pins, verification results
stream/…/<segment>.zst.age # WAL / binlog segments and their summaries
stream/position.json # the streamer's confirmed position
- 圧縮: 暗号化の前に、ポリシーのレベルで zstd を 1 回かけます。デフォルトで有効です
(ADR 0013)。
compression.algorithm: noneではデータをそのまま保存します。 - 暗号化: すべてのオブジェクトはクライアント側でストアの受信者に対して age で暗号化されます。バケットが平文を見ることは ありません。
- 完全性: すべてのオブジェクトのサイズと SHA-256 はマニフェストに記録され、読み取りのたびに検証されます。
- コミット: バックアップは
manifest.jsonが書き込まれて初めて存在します。その前にクラッシュしても、GC が削除する 孤立オブジェクトが残るだけで、完全に見えるバックアップが残ることはありません。
負荷制御¶
バックアップが本番環境と無秩序に競合することはありません。ホストごと、ターゲットごと、全体のスロット、帯域制限、優先度、
スケジュールのジッター、そしてサーバーのアクティブ接続が多すぎる、レプリケーション遅延が大きすぎる、または長時間実行中の
トランザクションがある間はフルバックアップを延期する 負荷ガード があります。これらはすべて
BackupPolicy で設定します。