はじめに
バックアップは、アプリケーションデータを復元できて初めて役に立ちます。この実験では、小規模な D1 データベースを SQL にエクスポートし、エクスポートしたファイルから破棄可能な 2 つ目のデータベースを再構築します。その後、元のデータベースを変更せずに、データと制約を比較します。
この実験は、2 件の合成チケットを使って独立して開始し、使用する D1 データベースは最大 2 つです。バックアップは LabEx VM 内に保存します。オブジェクトストレージのアカウントやバケットは使用しません。
自分の学習用アカウントと新しい VM を使用してください。セットアップでは、まず Node.js 22.22.0 を準備し、その後 /home/labex/project/ticket-database でプロジェクトローカルの Wrangler 4.131.1 と評価に必要な依存関係を npm install でインストールします。直接の依存関係のバージョンは固定されており、インストール時に専用の lockfile が作成されます。セットアップ中にクラウドへのログインや、評価対象のデータベース操作が実行されることはありません。個人のマシンで実行する場合は、プロジェクト内で npm install --save-dev wrangler@4.131.1 を実行して、同じバージョンの Wrangler をインストールしてください。
この演習では、D1 Free の利用枠内に収まる小規模な合成レコードを使用します。既存のアカウント使用量も利用枠に加算されます。購入済みのドメインは必要ありません。リソースの削除とログアウトの両方を確認するまで、この VM を保持してください。
この VM を認証し、アカウントを選択する
このステップでは、新しいターミナルを自分の学習用アカウントに接続します。Dashboard にログインしただけでは VM は認証されません。D1 の権限によって、データベースの作成、SQL の変更、削除が可能になります。認証する前に、Background Access を含む実際の同意画面の内容を確認してください。
準備済みのプロジェクトに移動し、固定された CLI のバージョンを確認します。
cd /home/labex/project/ticket-database
npx wrangler --version
4.131.1 と表示されることを確認します。デバイス認証を開始します。--device はブラウザーコードを表示し、--browser=false はブラウザーを自分で選択できるようにします。
npx wrangler login --device --browser=false --scopes account:read user:read d1:write
表示された URL をブラウザーで開き、現在のコードを入力します。学習用アカウントと権限を確認して認証を許可してください。ターミナルに成功が表示されるまで待ちます。パスワードやトークンをプロジェクトファイルに貼り付けないでください。
npx wrangler whoami --json
loggedIn: true を確認します。アカウントが 1 つだけ表示される場合でも、アカウントの name と id を読み取ってください。使用するアカウントの ID をコピーし、次の設定に入力します。次のシェル変数は 6 バイトの乱数(12 個の 16 進数文字)を使って、他の学習者との名前の衝突を避けます。ヒアドキュメントによって、JSON の行で囲まれた JSON が書き込まれます。中の $RUN は展開されます。
$schema の前のバックスラッシュは、この JSON キーを文字どおり保持します。$RUN は引き続き今回の実行に固有の名前に展開されます。
RUN=labex-c04-d06-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
"\$schema": "./node_modules/wrangler/config-schema.json",
"name": "$RUN",
"account_id": "YOUR_ACCOUNT_ID",
"main": "src/index.js",
"compatibility_date": "2026-09-15",
"workers_dev": true,
"preview_urls": false
}
JSON
ブロックを実行する前に、YOUR_ACCOUNT_ID を置き換えてください。RUN が利用できるように、このターミナルは開いたままにします。name は今回の実行を識別し、account_id はクラウド操作の対象アカウントを選択します。このファイルは通常の JSON であり、JSONC としても有効です。このファイルを書き込んだだけでは Worker はデプロイされません。
保持するデータベースを準備する
このステップでは、小規模な元のデータベースを作成します。セットアップによってチケットのスキーマが用意されています。ここでは、元のデータベースを変更せず、その制約を含めてエクスポートおよび再構築します。
破棄可能なクラウドデータベースを作成します。--binding DB はアプリケーションコードで使う短い名前を設定し、--update-config は実際の名前と UUID を wrangler.jsonc に記録します。--use-remote=false により、開発時にはローカル環境を使用します。
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
作成された名前と ID を読み取り、保存されたバインディングを確認します。
cat wrangler.jsonc
DB エントリに、今回の実行で作成したデータベースが指定されていることを確認します。バインディングは、コードとリソースを接続する設定済みの接続です。その UUID はクラウドデータベースを識別します。一方、--local を指定すると、この VM 内の別の SQLite データベースが使用されます。SQL コマンドでは、必ず --local または --remote のいずれかを指定してください。
cat schema.sql
npx wrangler d1 execute DB --remote --file schema.sql
エクスポートする前に、元のデータとスキーマを確認します。
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id; SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'tickets';"
チケットは 2 件あります。次の内容を記録してください。ID 1 は Cannot sign in で、状態は open です。ID 2 は Invoice copy で、状態は closed です。どちらも source は seed です。スキーマには、主キー、必須値、status の制約が含まれています。
完全な SQL バックアップをエクスポートする
このステップでは、移植可能な SQL ファイルを作成します。エクスポートには、テーブル定義とデータが SQL として記述されます。このファイルをインポートすると、別の場所にデータベースを再構築できます。これは、データベースをその場で履歴から復元する D1 Time Travel とは異なります。
--remote はクラウド上のソースを選択し、--output はこの VM に書き込むファイル名を指定します。--no-schema と --no-data を省略して、スキーマとデータの両方を含めます。
npx wrangler d1 export DB --remote --output backup.sql
確認を求められたら、エクスポート元のデータベースが正しいことを確認します。作成された小さなエクスポートファイルを確認します。
cat backup.sql
CREATE TABLE と、チケットの INSERT 文を探してください。エクスポート時のフォーマット、カラムの引用符、内部文は、手書きした元の SQL と異なる場合があります。ダウンロードが成功しただけでは、復元できるとは限りません。次のステップで、このファイルを使ってデータベースを再構築し、成果物をテストします。このファイルには合成データだけが含まれています。ファイルは VM 内に保持してください。R2 バケットは必要ありません。
別のデータベースを再構築する
このステップでは、空の 2 つ目のデータベースに復元します。元のデータベースは変更しません。別のターゲットを用意することで、アプリケーションのバインディングを変更する前に、復元されたデータを比較できます。
REBUILT というバインディングを使って、2 つ目のリソースを作成します。設定の更新によって、DB と並んで新しいバインディングが追加されます。
npx wrangler d1 create "$RUN-copy" --binding REBUILT --update-config --use-remote=false
cat wrangler.jsonc
2 つのバインディングでデータベース UUID が異なり、名前がそれぞれ期待どおりの -db と -copy になっていることを確認します。インポート先には REBUILT だけを指定します。
npx wrangler d1 execute REBUILT --remote --file backup.sql
これにより、エクスポートした SQL が新しいクラウド上のターゲットに対して実行されます。プロンプトが表示されたら、そのターゲットが正しいことを確認してください。次に、データベースを検索します。
npx wrangler d1 execute REBUILT --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id; PRAGMA table_info(tickets);"
行とカラム定義が元のデータベースと一致している必要があります。無効な INSERT を実行して、復元された制約を 1 つテストします。
npx wrangler d1 execute REBUILT --remote --command "INSERT INTO tickets (id, subject, status, source) VALUES (3, 'Invalid', 'lost', 'probe');"
CHECK constraint failed と表示されることを確認します。この意図的な失敗によって、3 件目の行が追加されてはいけません。両方のデータベースを再度読み取ります。
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
npx wrangler d1 execute REBUILT --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
どちらにも、元の 2 行だけが残っている必要があります。読み取り専用の確認として、Dashboard で 2 つの正確なリソース名を開きます。再構築したテーブルを確認する前に、それぞれの ID が異なることを確認してください。復元をテストするために、別のデータベースを上書きしてはいけません。

この例では、-copy データベースに復元された 2 件のチケットを示しています。生成された名前はこの実行例を識別するもので、あなたのリソース名と UUID は異なります。スクリーンショットで確認できるのは表示された行のみです。上記の CLI のエクスポート・インポートコマンドと独立したチェックで、再構築、スキーマの一致、制約の維持を検証しています。
破棄可能なリソースを削除する
このステップでは、VM の認証が有効な間に、この実験で作成したリソースだけを削除します。機能に関する確認をすべて終えてから実行してください。削除の確認が完了するまで、設定ファイルは保持します。
npx wrangler d1 delete REBUILT
npx wrangler d1 delete DB
プロンプトの内容を確認し、今回の実行で作成したデータベースだけを削除対象として確定します。その後、データベース一覧を表示します。
npx wrangler d1 list --json
成功したレスポンスに、記録した 2 つのデータベース名と UUID が表示されていないことを確認します。他のリソースは残っている場合があります。認証エラーやネットワークエラーだけでは、削除結果を判断できません。アクセスを解決してから、続行する前に一覧の取得を再実行してください。ログインしたまま、このステップの確認を実行します。
この VM の認証を終了する
このステップでは、独立した削除確認が成功した後にのみ、認証を終了します。ログアウトすると、この VM に保存された Wrangler の認証情報が削除されます。VM を閉じただけでは、クラウド上のクリーンアップは完了しません。
npx wrangler logout
npx wrangler whoami --json
loggedIn: false と表示されることを確認します。この未認証のクエリは、終了コードが 0 以外になる場合があります。構造化されたレスポンスにログアウト済みであることが明示されている場合に限り、それは想定された結果です。確認を完了してから、実験環境を終了してください。
まとめ
データベースのエクスポートと再構築を実践しました。データベースの結果を確認し、選択したアカウントとローカル状態を明示的に管理しました。最後に、ログアウトする前に破棄可能なリソースを削除しました。



