CockroachDB Basic(旧Serverless)で本番DBをローカルにRESTOREする
目的
CockroachDB Basic(旧Serverless)プランでBACKUP / RESTOREコマンドを実行し、本番DBをローカルに再現する手順を記載する。
背景
個人で利用している家計簿アプリのデータベースにCockroachDB Basicを利用している。
テーブル設計を大幅に変更する必要があり、それに伴いデータ移行を実施する必要があった。
ローカルで本番相当のデータを準備するために、本番DBのバックアップをローカル開発環境に復旧しようと考えた。
補足すると、個人情報はデータベースに基本的に入っていない。
これを実施するうえでBACKUP / RESTOREコマンドを利用した。
公式ドキュメントの通りだと、うまくいかなかったところがあるので、自分なりにうまく行った手順を記載する。
前提
- CockroachDB Basicを利用している。他のプランは利用経験がないため、スコープ外としている。
- Google Cloudを利用している。なので、バックアップファイルの保存先はGoogle Cloud Storageである。AWS,Azure等のオブジェクトストレージを保存対象にすることもできるが、この記事では対象外。
手順
- サービスアカウントを用意する。
- サービスアカウントキーをダウンロードする。
a. 組織ポリシー上、サービスアカウントキーを生成できないと、BasicプランだとBACKUPコマンドを実行できない。理由は後述する。 - サービスアカウントに適切なパーミッションを付与する。
- バックアップファイルの保存先となるGCSバケットを作成する。
- cockroach sqlコマンドでCockroachDB Clusterに接続、BACKUPコマンドを実行する。
- cockroach sqlコマンドでローカルで起動しているCockroachDBに接続、RESTOREコマンドを実行する。
1. サービスアカウントを用意する
Google Cloudのコンソール画面から IAM & Admin > Service Accountに移動する。
サービスアカウント名、ID、説明を記入し、サービスアカウントを作る。
この時点ではRoleを付与していない。
2. サービスアカウントキーをダウンロードする
手順1で作成したサービスアカウントに紐づくサービスアカウントキーを作成する。
ここで作成したサービスアカウントキーは手順5で利用される。
3. サービスアカウントに適切なパーミッションを付与する
私が試した限りだと、適切なパーミッションは以下3つである。
- storage.object.get
- storage.object.list
- storage.object.create
これらを付与したカスタムロールを作成し、このカスタムロールを手順1で作成したサービスアカウントに付与する。
4. バックアップファイルの保存先となるGCSバケットを作成する
バケットを作る。
5. cockroach sqlコマンドでCockroachDB Clusterに接続、BACKUPコマンドを実行する
cockroach sqlコマンドを以下のように実行すれば、リモートのCockroachDB Clusterに接続できる。接続方法の詳細はConnect to a CockroachDB Clusterを読むと良い。
${...}は変数として扱い、読み手の環境に合わせた値を適宜埋め込んでほしい。
cockroach sql --url "postgresql://${DB_USERNAME}:${DP=PASSWORD}@${CLUSTER_HOSTNAME}:26257/${DB_NAME}?sslmode=verify-full"
その後、CockroachDB SQL Shell上で以下を実行する。
> BACKUP DATABASE ${DB_NAME} INTO "gs://${GCS_BUCKETNAME}?AUTH=specified&CREDENTIALS=${CREDENTIALS}" AS OF SYSTEM TIME '-10s';
GCS_BUCKETNAMEは手順4で作成したバケット名を利用する。
CREDENTIALSは手順2で作成したサービスアカウントキーをbase64でエンコードした文字列を利用する。エンコードは以下のコマンドで実行できるはず。
echo /path/to/service_account_key.json | base64
BACKUPコマンドを実行すると、データ量にもよるが、およそ1000件ほどのレコード数だと数分でジョブが完了し、GCSにバックアップファイルが作成される。
ここで先述した「サービスアカウントキーが必要な理由」を説明する。
GCSを利用する場合、認証方法は2つある(docs)
- 明示的な認証
- 暗黙的な認証
それぞれの説明は上記のdocsを読んで欲しい。
最初は暗黙的な認証を利用しようと、以下のコマンドを実行した(docs)。
> BACKUP DATABASE ${DB_NAME} INTO "gs://${GCS_BUCKETNAME}?AUTH=implicit&ASSUME_ROLE=${SERVICE_ACCOUNT_EMAIL} AS OF SYSTEM TIME '-10s';
だが、このコマンドは失敗した。エラーメッセージには 対象クラスターは '--external-io-disable-implicit-credentials'オプションを使って起動されている。なので、暗黙的な認証を利用できない(意訳)と記載があった。
Basicプランは起動オプション等を変更することができないので、明示的な認証を利用するほかない。
つまり、サービスアカウントキーが必須である。
おそらく他のプランだとこの辺りを設定できると思うので、Basicプラン限定の話だと思われる。
6. cockroach sqlコマンドでローカルで起動しているCockroachDBに接続、RESTOREコマンドを実行する
ローカルで起動しているCockroachDBにcockroach sqlコマンドで接続する。
$ cockroach sql --insecure
その後、RESTOREコマンドを実行する。
> RESTORE DATABASE ${DB_NAME} FROM LATEST IN "gs://${GCS_BUCKETNAME}?AUTH=specified&CREDENTIALS=${CREDENTIALS};
成功すれば、ローカルに${DB_NAME}と命名されたデータベースが作成され、無事に本番データをローカルに再現することができる。
最後に
CockroachDBはOSSであり、クラウド環境とローカル環境で同じプログラムを動かすことができる。
それゆえに、こういったデータ復旧がやりやすいのは一つの利点だと考えている。
他にもいくつか利点を感じるので、ぜひ採用を検討してほしい。
ただ、、、日本法人が存在しないので、、、悲しいです。
Discussion