> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casebender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ストレージ移行ランブック

> データ損失なくプロバイダーストレージをコピー、検証、カットオーバー、およびロールバックする

このランブックは、オブジェクトキーを変更せずにCaseBenderオブジェクトを移行します。
コピー優先セマンティクスを使用します。ソースはロールバック
ウィンドウが期限切れになるまで権威であり、無傷のままです。ローカルファイルシステム、MinIO/S3互換
ストレージ、AWS S3、および `rclone` リモート経由のGCSに適用されます。

## 前提条件

* 両方のプロバイダーについて、ストレージサポートポリシーとリリースノートを読む。
* リリースがプロバイダー中立の永続削除アウトボックスを使用することを確認する。履歴の
  MinIO専用削除ギャップは修正済みです。その古い
  制限を新しい設計に持ち込まないでください。
* 宛先の容量、暗号化、バージョニング、保持、ライフサイクル、
  オブジェクトサイズ、メタデータ、および命名動作を確認する。
* 最小権限のソース読み取りおよび宛先書き込み移行アイデンティティを作成する。
* TLS信頼を設定する。`--no-check-certificate` を使用してはならない。
* PostgreSQLとソースストレージの一貫性バックアップを取得してテストする。
* オブジェクト数、合計バイト、ソースバージョン/スナップショット、および設定を記録する。
* 書き込み静止とロールバックを許可する変更ウィンドウを設定する。

権威あるPostgreSQLオブジェクトインベントリを生成して保護します。

```sh theme={null}
pnpm storage:backup-verify inventory \
  --output '<protected-manifest.json>'
chmod 600 '<protected-manifest.json>'
```

移行するすべての項目は、正確なソースオブジェクトバージョン/世代、
サイズ、およびSHA-256を識別する必要があります。PostgreSQLとそれらの正確なバージョンは1つの一貫性セットです。
バージョンが記録されている場合、浮動する「latest」オブジェクトを移行しないでください。

以下の例は `source:casebender` と `destination:casebender` を使用します。rclone
設定とログはリポジトリの外に置き、機密として保護します。

## 1. インベントリとドライラン

```sh theme={null}
rclone version
rclone size source:casebender --json > source-size.before.json
rclone lsf source:casebender --recursive --files-only \
  > source-objects.before.txt
rclone copy source:casebender destination:casebender \
  --checksum --metadata --dry-run --log-level INFO \
  --log-file migration-dry-run.log
```

サポートされないメタデータの警告を確認します。プロバイダー固有の暗号化、保持、
リーガルホールド、ACL、およびバージョン履歴は、通常のオブジェクトメタデータとしてコピーされない場合があります。
それらの制御は宛先で設定し、バックアップ内のソースバージョンを
保全します。初期コピーに `sync` を使用してはなりません。宛先
オブジェクトを削除する可能性があるためです。

## 2. アプリケーション稼働中のシードコピー

```sh theme={null}
rclone copy source:casebender destination:casebender \
  --checksum --metadata --fast-list --transfers 8 --checkers 16 \
  --log-level INFO --log-file migration-seed.log
```

プロバイダーのスロットル制限未満に同時実行を調整します。失敗したオブジェクトを再試行し、
完全なログを保持します。ETagから整合性を推測しないでください。マルチパートおよび暗号化
オブジェクトは非MD5のETagを持つ場合があります。

## 3. 書き込みを静止し、一貫性ポイントを取得する

リリースのメンテナンス手順を使用して、ユーザーおよび統合の書き込みをブロックします。
キューがドレインされるか永続的に保持された後にのみ、取り込みとワーカーを一時停止します。
データベースのタイムスタンプ/LSN、ソースバケットバージョン/スナップショット、およびデプロイ
レプリカを記録します。ストレージ書き込みが発生していないことを検証します。

最終差分を実行します。

```sh theme={null}
rclone copy source:casebender destination:casebender \
  --checksum --metadata --fast-list --transfers 8 --checkers 16 \
  --log-level INFO --log-file migration-final.log
```

ソースを削除または無効にしないでください。

## 4. カットオーバー前の検証

```sh theme={null}
rclone check source:casebender destination:casebender \
  --download --one-way --combined migration-check.txt
rclone size source:casebender --json > source-size.final.json
rclone size destination:casebender --json > destination-size.final.json
```

`rclone check --download` はダウンロードした内容をハッシュし、プロバイダーETagの
曖昧さを避けます。欠損、変更、または読み取り不可オブジェクトがゼロであることを要求します。
プロバイダーマーカーオブジェクトまたはローカル `.meta.json` サイドカーによる件数差を調査し、
記録された説明なしに差を免除しないでください。

アプリケーションネットワークから宛先契約テストを実行します。

```sh theme={null}
STORAGE_TEST_PROVIDER=s3 \
STORAGE_TEST_ENDPOINT=https://storage.example.com \
STORAGE_TEST_BUCKET=casebender \
AWS_REGION=us-east-1 \
./scripts/storage/validate-storage.sh
```

GCSまたはローカルの例については、スクリプトの使用方法を参照してください。高価値の証拠、
大きなマルチパートオブジェクト、Unicode名、空ファイル、MIMEメタデータ、および保持された
オブジェクトもサンプリングします。

## 5. カットオーバー

1. 暗号化された変更記録に、古いプロバイダー設定とSecretリソースバージョンを
   保存する。
2. `StorageMigrationLedger` エントリが `VERIFIED` であることを確認する。移行
   プロセッサーは先にコピーし、読み戻し、SHA-256を検証し、宛先
   プロバイダーバージョンを記録してから、`CUTOVER` に遷移します。
3. 明示的なプロバイダープロファイルと資格情報のみを変更する。バケット
   内容と永続キーを保全する。
4. Webアプリケーションを再起動し、`/api/health/ready` を待つ。
5. アプリケーションのアップロード/ダウンロード/list/コピー/削除テストを実行し、SHA-256を検証する。
6. 複数の経過時間とサイズにわたる既存の添付と証拠を検証する。
7. ワーカーと取り込みを再開し、その後ユーザー書き込みを再開する。
8. ロールバックウィンドウ中、ストレージエラー、失敗した削除、レイテンシ、スロットリング、キュー深度、および
   監査イベントを継続的に監視する。

リリース固有の移行が明示的に要求しない限り、
データベースキーの書き換えを実行しないでください。

文書化された互換ウィンドウ中、レガシー参照はソースから
読み取られ、台帳バックのオブジェクトは宛先を使用する場合があります。無制限のデュアル
書き込みを実装しないでください。リコンシリエーションが欠損参照がないことを確認し、ロールバック承認が許可した後にのみ、
レガシー読み取りを閉じてください。

## 6. ロールバック

ロールバックは、古いソースが保持され、新しい書き込みを
調整できる間のみ安全です。

1. メンテナンスモードに再入り、書き込みを静止する。
2. カットオーバー以降に宛先に書き込まれたすべてのオブジェクトを記録する。
3. 削除なしで、逆差分をソースにコピーする。

```sh theme={null}
rclone copy destination:casebender source:casebender \
  --checksum --metadata --fast-list \
  --log-level INFO --log-file rollback-copy.log
rclone check destination:casebender source:casebender \
  --download --one-way --combined rollback-check.txt
```

4. クリーンなチェックを要求してから、以前のプロバイダー設定と
   資格情報バージョンを復元する。
5. 再起動し、アプリケーションのライフサイクル/整合性テストを実行して、トラフィックを再開する。
6. インシデント/変更レビューが完了するまで、両方のストアとすべてのエビデンスを保持する。

ソース保持またはポリシーが逆コピーを妨げる場合は停止し、記録された
一貫性バックアップを復元します。破壊的な同期を即興で行わないでください。

## 7. クローズアウト

* 最終件数/バイトを調整し、ハッシュ、ログ、ツールバージョン、承認、
  設定バージョン、およびサンプリングしたアプリケーション結果をアーカイブする。
* 一時的な移行資格情報をローテーションする。
* 承認済みロールバック期間中、ソースを読み取り専用で保持する。
* 正式なサインオフと法務/保持レビューの後、
  プロバイダーの監査済み廃棄プロセスを使用してソースデータを削除する。
* プロバイダー製品/バージョン、TLS/CA詳細、
  契約結果、性能結果、バックアップ結果、およびロールバック演習でサポート記録を更新する。

ソース廃棄前に、隔離リストア検証を実行します。

```sh theme={null}
pnpm storage:backup-verify verify-restore \
  --manifest '<protected-manifest.json>' \
  --target-profile '<isolated-restore-profile>' \
  --isolated-prefix 'tenants/<test-tenant>/restore-verification/<exercise-id>' \
  --evidence-output '<sanitized-restore-evidence.json>'
```

実際の復旧ポイントと復旧時間を記録します。測定済みのリストアとロールバック演習のない
RPO/RTO目標はエビデンスではありません。

## プロバイダー固有の注意点

* **S3/Ceph RGW:** バージョンIDと削除マーカーを保全する。通常のコピーでは
  Object Lock/リーガルホールド状態が保持されない場合があります。正確な製品バージョンと
  プライベートCAを再適格性確認します。
* **GCS:** 数値世代を保全する。バケット保持、オブジェクト保持、
  イベントベースホールド、およびCMEKポリシーは、別途宛先での証明が必要です。
* **Azure:** BlobバージョンIDを保全する。不変性とリーガルホールドは
  宛先固有であり、コピーされたBlobは新しいバージョンIDを受け取ります。
* **レガシーMinIO:** 元のボリュームスナップショットとS3 APIエクスポートの両方を保持する。
  MinIOの内部ファイルシステムレイアウトを別のプロバイダーにインポートしてはなりません。

[バックアップとリストア](/ja/deployment/storage-backup-restore) および
[MinIOライフサイクル](/ja/deployment/storage-minio-lifecycle) を参照してください。
