💽

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等のオブジェクトストレージを保存対象にすることもできるが、この記事では対象外。

手順

  1. サービスアカウントを用意する。
  2. サービスアカウントキーをダウンロードする。
    a. 組織ポリシー上、サービスアカウントキーを生成できないと、BasicプランだとBACKUPコマンドを実行できない。理由は後述する。
  3. サービスアカウントに適切なパーミッションを付与する。
  4. バックアップファイルの保存先となるGCSバケットを作成する。
  5. cockroach sqlコマンドでCockroachDB Clusterに接続、BACKUPコマンドを実行する。
  6. 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