Cloud Spanner 移行評価ツール ~ HarbourBridge

Ryuji Tazaki
google-cloud-jp
Published in
19 min readJan 26, 2022

はじめに ~ HarbourBridge のご紹介 ~

Cloud Spanner は Google Cloud で提供されている、高可用性を有する水平スケール可能なデータベースです。その特徴の詳細については前回の記事をご参照ください。

Cloud Spanner を利用するにあたって、既存のデータベースからデータを移行して評価したいというケースが有るかと思います。今回はその様な場合に役立つ移行ツールの一つとして Cloud Spanner Ecosystem で提供されている、HarbourBridge というオープンソースツールを紹介します。

HarbourBridge を利用すると、MySQL や PostgreSQL 、 DynamoDB のデータを直接 Cloud Spanner へ移行したり、事前に取得したダンプデータを Cloud Spanner へ取り込むことが可能です。「移行評価ツール」としての側面が強いので、CDC (継続的な変更データの移行) などの高度な機能は有さないものの、シンプルな操作で Cloud Spanner 向けにスキーマとデータの変換及び移行 ( 約 100 GB まで ) を行ってくれます。評価目的で、とりあえず既存で利用しているデータベースのデータを取り込んでみたいといったときに便利なツールです。

本記事では HarbourBridge を利用して、ソースデータベースから事前に取得したダンプデータを Cloud Spanner インスタンスへ取り込む手順を紹介します。記事内で利用するダンプデータは HarbourBridge がサンプルで提供しているショッピングカートデータのダンプデータ (cart.pg_dump) です。

HarbourBridge のインストール

HarbourBridge を導入する環境の要件として、Google Cloud SDK および Go 言語が必要です。今回は必要な条件が整っている Cloud Shell 環境へ HarbourBridge を導入して利用する手順を紹介します。

ただし Cloud Shell 環境のストレージ容量は ホームディレクトリで 5GB の容量制限があり、不足した場合に拡張ができない点に注意が必要です。HarbourBridge が生成するログファイルや一時ファイルでストレージ容量が不足する場合には、 Compute Engine VM インスタンス等を利用することを検討してください。

(1) Cloud Console へログインし、画面右上の Cloud Shell アイコンを選択して Cloud Shell を起動します。※ Cloud Console を開いたら、想定したプロジェクトが選択されていることも併せて確認しましょう。

(2) 画面下に起動した Cloud Shell 内にて、下記のコマンドを実行して、HarbourBridge をインストールします。

git clone https://github.com/cloudspannerecosystem/harbourbridge
cd harbourbridge
go run github.com/cloudspannerecosystem/harbourbridge help

(3) 最終的に下記のヘルプメッセージが出てきたら、インストールは完了です。

Cloud Spanner インスタンスの準備

次にデータを取り込む先となる Cloud Spanner のインスタンスを準備します。今回は評価目的ということで費用を抑えるため、2021 年 5 月に作成可能となった 100 処理単位 ( 0.1 ノード ) のサイズのインスタンスを作成して利用します。

引き続き Cloud Shell にてコマンドを実行して作成します。

(1) Cloud Spanner API を有効化します。

gcloud services enable spanner.googleapis.com

(2) Cloud Spanner インスタンス “test-inst” を作成します。

processing-units オプションへ 100 を指定して、100 処理単位のサイズのインスタンスを作成しています。

gcloud beta spanner instances create test-inst \
--config=regional-asia-northeast1 \
--processing-units=100 \
--description="HarbourBridge Test"

(3) 作成したインスタンスの state が READY となっていることを確認します。

$ gcloud beta spanner instances describe test-inst
config: projects/demo-project-001/instanceConfigs/regional-asia-northeast1
displayName: HarbourBridge Test
name: projects/ryutaza-demo-project-001/instances/test-inst
processingUnits: 100
state: READY

ダンプデータのアップロード

HarbourBridge による取り込みのため、ダンプデータを HarbourBridge が読み込める場所に配置する必要があります。ここでは (1) Cloud Shell 環境へアップロードする方法と、(2) Cloud Storage バケットへアップロードする方法をご紹介します。先に記載したように Cloud Shell 環境はストレージ容量に制限がありますので、大きめのダンプデータを取り込む場合には、Cloud Storage バケットを利用しましょう。

ちなみに HarbourBridge インストール時に harbourbridge/examples ディレクトリ配下にもサンプルデータがアップロードされているため、こちらを利用する場合は、このアップロード手順はスキップ可能です。

(1) Cloud Shell 環境へのアップロード

(1)-1 Cloud Shell ウィンドウの右上にあるドロップダウンメニューから、アップロードを選択します。

(1)-2 [ファイル選択]ボタンを選択して、ローカルにあるアップロードしたいダンプファイルを指定したら、[アップロード]ボタンを選択します。

(1)-3 ダンプファイルがホームディレクトリへアップロードされたことを確認します。併せてファイルのフルパスを確認しておきます。

$ head /home/demo_uesr/cart.pg_dump
--
-- PostgreSQL database dump
--
...

(2) Cloud Storage バケットへのアップロード

(2)-1 Cloud Storage バケットの作成

Cloud Storageの[ブラウザ]ページへアクセスして、[バケットを作成]を選択します。※既存のバケットを利用する場合には、スキップして次の手順へ進みます。

[バケットの作成]ページで バケットの名前を設定したら、必要に応じてその他の設定も修正しましょう。最後に[作成]ボタンを選択して、バケットを作成します。

(2)-2 ダンプデータのアップロード

バケットの作成が完了すると、[バケットの詳細]ページへ移動するため、[ファイルをアップロード]を選択して、取り込みたいダンプファイルをアップロードします。

ここではサンプルの cart.pg_dumpをアップロードしました。

アップロードしたファイルをクリックすると、[オブジェクトの詳細]ページへ移動し、gsutil URI が確認できるのでこれを記録します。

(2)-3 アクセスの確認

Cloud Shell にて gsutil コマンドを実行し、先に確認した gsutil URI を利用してダンプファイルの内容を参照できることを確認します。

$ gsutil cat gs://test-bucket-xxxxxx/cart.pg_dump | head
--
-- PostgreSQL database dump
--
...

HarbourBridge の実行

HarbourBridge を実行して作成した Cloud Spanner インスタンスへデータを取り込みましょう。harbourbridge コマンドを利用するために、改めて HarbourBridge を配置したディレクトリに移動し、Aliasを設定します。

cd ~/harbourbridge
alias harbourbridge="go run github.com/cloudspannerecosystem/harbourbridge"

新規データベースを作成し、Cloud Storage 上のダンプデータを取り込みます。ファイルをCloud Shell へアップロードしたか、Cloud Storage バケットへアップロードしたかに応じて、“file=” のあとにダンプファイルのフルパス、若しくは gsutil URI を指定します。

harbourbridge schema-and-data \
-source postgres \
-source-profile file=<ファイルフルパス or gsutil URI> \
-target-profile instance=<インスタンス名>,dbname=<作成するデータベース名>

下記のコマンド例では “test-db” というデータベースを作成して、Cloud Storage へアップロードされたダンプデータを取り込んでいます。

$ harbourbridge schema-and-data \
> -source postgres \
> -source-profile file=gs://test-bucket-xxxxxx/cart.pg_dump \
> -target-profile instance=test-inst,dbname=test-db
...
Schema conversion: EXCELLENT (all columns mapped cleanly).
Data conversion: EXCELLENT (all 6 rows written to Spanner).
See file 'pg_dump_2022-01-20_9205-4b54.report.txt' for details of the schema and data conversions.

Schema/Data conversion の出力から、移行結果の概要が確認できます。harbourbridge コマンドはその他にもオプションを指定して、移行方法を調整可能です。詳細な説明はこちらで確認できます。

出力ファイルの確認

HarbourBridge の実行後、同一のディレクトリには移行の評価に役立つ下記のようなレポートファイル (*report.txt) が出力されるので、確認しましょう。このレポートは、移行元となった DB から Cloud Spanner に移行するにあたって、自動スキーマ変換の結果や、検出された非互換などがレポートされます。その他の出力されるファイルについては、 Files Generated by HarbourBridge の説明を併せて参考にしてください。

----------------------------
Summary of Conversion
----------------------------
Schema conversion: EXCELLENT (all columns mapped cleanly).
Data conversion: EXCELLENT (all 6 rows written to Spanner).
...
----------------------------
Statements Processed
----------------------------
Analysis of statements in pg_dump output, broken down by statement type.
schema: statements successfully processed for Spanner schema information.
data: statements successfully processed for data.
skip: statements not relevant for Spanner schema or data.
error: statements that could not be processed.
--------------------------------------
schema data skip error statement
--------------------------------------
0 0 2 0 AlterTableStmt.AlterTableCmd
2 0 0 0 AlterTableStmt.AlterTableCmd.Constraint
0 2 0 0 CopyStmt
2 0 0 0 CreateStmt
0 0 4 0 GrantStmt
0 0 1 0 SelectStmt
See github.com/pganalyze/pg_query_go for definitions of statement types
(pganalyze/pg_query_go is the library we use for parsing pg_dump output).
----------------------------
Table cart
----------------------------
Schema conversion: EXCELLENT (all columns mapped cleanly).
Data conversion: EXCELLENT (all 3 rows written to Spanner).
Note
1) Some columns have source DB type 'timestamp without timezone' which is mapped
to Spanner type timestamp e.g. column 'last_modified'. Spanner timestamp is
closer to PostgreSQL timestamptz.
----------------------------
Table products
----------------------------
Schema conversion: EXCELLENT (all columns mapped cleanly).
Data conversion: EXCELLENT (all 3 rows written to Spanner).
----------------------------
Unexpected Conditions
----------------------------
There were no unexpected conditions encountered during processing.

Cloud Spanner データベースの確認

取り込まれたデータを spanner-cli を用いて確認します。spanner-cli は Cloud Spanner の CLI ツールで、Cloud Spanner Ecosystemで提供されているオープンソースツールの一つです。mysql コマンドや、psql コマンドになれている方にとって、類似したインターフェースが提供されていて使いやすいツールです。

(1) spanner-cli のインストール

Cloud Shell へ spanner-cli のインストールします。

go install github.com/cloudspannerecosystem/spanner-cli@latest

spanner-cli を利用してデータベースへの接続を行います。

spanner-cli -p $GOOGLE_CLOUD_PROJECT -i test-inst -d test-db

(2) データベースの確認

show コマンドや select 文を用いて、データベース及びテーブルが作成されていること、データが取り込まれていることが確認できます。

spanner> show databases;
+----------+
| Database |
+----------+
| test-db |
+----------+
1 rows in set (0.07 sec)
spanner> show tables;
+-------------------+
| Tables_in_test-db |
+-------------------+
| cart |
| products |
+-------------------+
2 rows in set (0.14 sec)
spanner> select * from cart;
+-------------------+------------+----------+----------------------+
| user_id | product_id | quantity | last_modified |
+-------------------+------------+----------+----------------------+
| 901e-a6cfc2b502dc | abc-123 | 1 | 2020-07-20T05:10:26Z |
| 901e-a6cfc2b502dc | axd-673 | 2 | 2020-07-20T05:10:43Z |
| a86b-82493320a775 | zxi-631 | 5 | 2020-07-20T05:10:46Z |
+-------------------+------------+----------+----------------------+
3 rows in set (5.83 msecs)
spanner> select * from products;
+------------+--------------------+--------+------------+
| product_id | description | price | date_added |
+------------+--------------------+--------+------------+
| abc-123 | Blue suede shoes | 141.99 | 2020-06-06 |
| axd-673 | Antique typewriter | 99.99 | 2020-06-07 |
| zxi-631 | Glass vase | 55.5 | 2020-06-10 |
+------------+--------------------+--------+------------+
3 rows in set (1.63 msecs)

(2) テーブル定義の確認

テーブル定義を確認すると、ダンプファイルの bigint 型が INT64 型へ変換されているなど、取り込み時にスキーマが Cloud Spanner に併せて変換されていることが確認できます。

<<ダンプファイルから抜粋した cart テーブルの定義>>

CREATE TABLE public.cart (
user_id character varying(20) NOT NULL,
product_id character varying(20) NOT NULL,
quantity bigint,
last_modified timestamp without time zone
);
...
ALTER TABLE ONLY public.cart
ADD CONSTRAINT cart_pkey PRIMARY KEY (user_id, product_id);

<< Cloud Spanner 取り込み後の cart テーブルの定義>>

spanner> show create table cart;
+-------+------------------------------------+
| Table | Create Table |
+-------+------------------------------------+
| cart | CREATE TABLE cart ( |
| | user_id STRING(20) NOT NULL, |
| | product_id STRING(20) NOT NULL, |
| | quantity INT64, |
| | last_modified TIMESTAMP, |
| | ) PRIMARY KEY(user_id, product_id) |
+-------+------------------------------------+
1 rows in set (0.57 sec)

HarbourBridge が行うスキーマ及びデータ変換のルールは、 Schema ConversionData Conversion にて確認できます。

まとめ

今回確認したように HarbourBridge を利用すると、ソースデータベースのダンプデータを Cloud Spanner へ取り込むことで、移行評価が手軽に行なえます。また指定するオプションを変更することで、スキーマだけの取り込みやデータだけの取り込みにも対応しています。

下記ブログでは今回紹介できなかった MySQL や DynamoDB から直接データを取り込む際の手順について解説されています。

--

--

Ryuji Tazaki
google-cloud-jp

Partner Engineer, Data Management Solution @Google Cloud Japan. Opinions are my own and not the views of my employer.