tigris-snapshots-forking について
Tigris Snapshots and Forking は、Tigris オブジェクトストレージのバケットスナップショットとフォークの操作を説明するスキルです。復旧やテスト、データの分離コピーが必要な開発者向けで、フォーク内の削除が元データに影響しない仕組みを扱います。
主な機能
- 01バケット全体の特定時点の状態を記録
- 02スナップショット一覧とバージョン指定の読み取り
- 03スナップショットから分離したバケットを作成
- 04コピーオンライト方式のフォーク
活用シーン
- 01本番データを使った開発用サンドボックス作成
- 02AI エージェント環境向けのデータ複製
- 03移行前のバックアップとロールバック
- 04本番データを使った負荷テスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tigrisdata/ skills --skill tigris-snapshots-forkingインストール後、Claude Code で/tigris-snapshots-forkingを入力して読み込まれたか確認します。
同梱ファイルmetadata.jsonREADME.md
詳細
Tigris のスナップショットとフォーク
前提条件
ほかの作業を始める前に、まだ利用できない場合は Tigris CLI をインストールしてください。
tigris help || npm install -g @tigrisdata/cli
インストールが必要な場合は、ユーザーに「Tigris のオブジェクトストレージを操作できるように、Tigris CLI(@tigrisdata/cli)をインストールしています。」と伝えてください。
概要
スナップショットは、ある時点でのバケット全体を記録します。フォークでは、コピーオンライトを使用して、スナップショットからすぐに分離されたコピーを作成できます。
**基本原則:**スナップショットとフォークは、データの削除から保護します。フォーク内のデータをすべて削除しても、ソースバケットのデータはそのまま残ります。
スナップショットが重要な理由
オブジェクトストレージは、多くのシステムで主要なデータストアとして使われています。そのため、安全機能が必要です。
- 特定時点への復旧 - 誤って削除した場合やデータが破損した場合に復元できます
- バージョン管理 - リリースなど、意味のある状態にタグを付けられます
- 再現性 - デバッグやテストのために、正確な環境を再現できます
- 削除保護 - フォークを破棄しても、ソースには影響しません
従来のオブジェクトのバージョン管理は、オブジェクトごとにしか機能しません。バケットを特定の時点の状態に戻すには、各オブジェクトを個別に確認して復元する必要があります。Tigris のスナップショットでは、バケット全体の状態を瞬時に記録できます。
フォークが重要な理由
フォークを使うと、テラバイト規模のデータでも、バケットの分離されたコピーをすぐに作成できます。
- 開発者用サンドボックス - 実際の本番データを安全に使ってテストできます
- AI エージェント環境 - 依存関係をあらかじめ読み込んだエージェントを起動できます
- 負荷テスト - リスクを伴わずに本番データを使用できます
- フィーチャーブランチのテスト - 実験用の環境を並行して利用できます
- トレーニング実験 - ソースに影響を与えずに、データセットをフォークしてテストできます
**仕組み:**Tigris は、不変のオブジェクトと、時間を逆順に並べたタイムスタンプを使用します。新しいデータで上書きされるまでは、フォークから親スナップショットのデータが読み込まれます。そのため、データをコピーする必要がなく、フォークは実質的に無料で作成できます。
クイックリファレンス
| 操作 | 関数 | 主なパラメーター |
|---|---|---|
| スナップショットを作成 | createBucketSnapshot(options) | name, sourceBucketName |
| スナップショットを一覧表示 | listBucketSnapshots(sourceBucketName) | sourceBucketName |
| フォークを作成 | createBucket(name, options) | sourceBucketName, sourceBucketSnapshot |
スナップショットを作成する
import { createBucketSnapshot } from "@tigrisdata/storage";
// Snapshot default bucket
const result = await createBucketSnapshot();
if (result.error) {
console.error("Error:", result.error);
} else {
console.log("Snapshot version:", result.data?.snapshotVersion);
// Output: { snapshotVersion: "1751631910169675092" }
}
// Named snapshot for specific bucket
const result = await createBucketSnapshot("my-bucket", {
name: "backup-before-migration",
});
if (result.error) {
console.error("Error:", result.error);
} else {
console.log("Named snapshot:", result.data?.snapshotVersion);
}
**前提条件:**バケットの作成時に、enableSnapshot: true を指定する必要があります。
スナップショットを一覧表示する
import { listBucketSnapshots } from "@tigrisdata/storage";
// List snapshots for default bucket
const result = await listBucketSnapshots();
if (result.error) {
console.error("Error:", result.error);
} else {
console.log("Snapshots:", result.data);
// [
// {
// name: "backup-before-migration",
// version: "1751631910169675092",
// creationDate: Date("2025-01-15T08:30:00Z")
// }
// ]
}
// List snapshots for specific bucket
const result = await listBucketSnapshots("my-bucket");
スナップショットからフォークを作成する
import { createBucket, createBucketSnapshot } from "@tigrisdata/storage";
// First, create a snapshot
const snapshot = await createBucketSnapshot("agent-seed", {
name: "agent-seed-v1",
});
const snapshotVersion = snapshot.data?.snapshotVersion;
// Fork from snapshot
const agentBucketName = `agent-${Date.now()}`;
const forkResult = await createBucket(agentBucketName, {
sourceBucketName: "agent-seed",
sourceBucketSnapshot: snapshotVersion,
});
if (forkResult.error) {
console.error("Error:", forkResult.error);
} else {
console.log("Forked bucket created");
// agent-${timestamp} has all data from agent-seed at snapshot time
// Can modify/delete freely - agent-seed is unaffected
}
スナップショットのバージョンから読み込む
フォークを作成せずに、過去のデータにアクセスします。
import { get, list } from "@tigrisdata/storage";
// Get object as it was at snapshot
const result = await get("config.json", "string", {
snapshotVersion: "1751631910169675092",
});
// List objects as they were at snapshot
const result = await list({
snapshotVersion: "1751631910169675092",
});
削除保護の動作
import { remove, get } from "@tigrisdata/storage";
// In forked bucket, delete everything
await remove("hello.txt", { config: { bucket: "agent-fork" } });
// Fork appears empty
const forkResult = await get("hello.txt", "string", {
config: { bucket: "agent-fork" },
});
// forkResult.error === "Not found"
// But source bucket still has data
const sourceResult = await get("hello.txt", "string", {
config: { bucket: "agent-seed" },
});
// sourceResult.data === "Hello, world!"
フォークを削除しても、影響を受けるのはフォークだけです。ソースデータには、親バケットとすべてのスナップショットから引き続きアクセスできます。
ユースケース
開発者用サンドボックス
// Create snapshot of production data
await createBucketSnapshot("production", {
name: "dev-sandbox-seed",
});
// Fork for each developer
const devBucket = await createBucket(`dev-${developerName}`, {
sourceBucketName: "production",
sourceBucketSnapshot: "...",
});
// Developer can test and modify freely
AI エージェント環境
// Store agent dependencies in seed bucket
await put("model.bin", modelData);
await put("config.json", agentConfig);
// Snapshot the seed
const snapshot = await createBucketSnapshot("agent-seed", {
name: "v1",
});
// Spin up new agent instance with fork
const agentBucket = `agent-${Date.now()}`;
await createBucket(agentBucket, {
sourceBucketName: "agent-seed",
sourceBucketSnapshot: snapshot.data?.snapshotVersion,
});
// Agent has everything and can modify freely
await startAgent(agentBucket);
移行前のバックアップ
// Before risky operation
await createBucketSnapshot("production", {
name: "before-migration-v2",
});
// Run migration
// If disaster strikes, fork from snapshot to recover
const rollback = await createBucket("production-restored", {
sourceBucketName: "production",
sourceBucketSnapshot: "...",
});
よくある間違い
| 間違い | 修正方法 |
|---|---|
| スナップショットが有効でないバケットのスナップショットを作成する | enableSnapshot: true を指定してバケットを再作成する |
| フォークがソースに影響すると考える | フォークは分離されています。ソースは変更されません |
| スナップショットに名前を付けない | 名前を付けるとスナップショットを見つけやすくなります |
| 間違ったストレージ階層を使用する | スナップショット用バケットでは STANDARD 階層が必要です |
制限事項
- 既存のバケットではスナップショットを有効にできません(新しいバケットを作成する必要があります)
- スナップショット用バケットでは STANDARD ストレージ階層が必要です
- スナップショット用バケットでは、ライフサイクル移行や TTL はサポートされません
仕組み(詳細)
スナップショットは、Unix エポックからの経過時間をナノ秒単位で表す単一の 64 ビット整数です。Tigris はタイムスタンプを逆順でオブジェクトに保存するため、最新バージョンが先に並びます。スナップショットを作成すると、Tigris は現在時刻を記録します。スナップショットから読み取る際は、そのタイムスタンプより前にある最新のオブジェクトバージョンを検索します。
フォークでは再帰的な間接参照が追加されます。子バケットのオブジェクトが親のオブジェクトを上書きし、存在しないオブジェクトは親のスナップショットを再帰的にたどります。データをコピーせず、メタデータのポインターだけを使うため、フォークは瞬時に完了します。