Google Cloud のデータベースのマネージドサービスである、Cloud SQL から先日新たに Enterprise と Enterprise Plus というエディションがGAされました。
以前から Cloud SQL を利用されている場合は Enterprise エディションに区分されるため、Enterprise Plus を利用するには Database Migration Service を使ったデータベース移行が必要となります。

今回は Enterprise から Enterprise Plus へ移行するにあたって、どのような設定をすれば良いのか、サンプルデータを用いて実際に試してみます。

利用するサービス

Enterprise Plus

Enterprise Plus エディションは 2023/7 に GA された Cloud SQL の新機能で、パフォーマンスの向上やメンテナンスのダウンタイム低減など様々な恩恵があります。
詳細については弊社の齋藤のブログに纏まっていますので、こちらをご参照ください。

Database Migration Service

Google Cloud の Database Migration Service(以下DMS)は、異なるデータベース間でデータを効率的に移行、同期、変換するためのサービスです。
オンプレミスや他クラウドプロバイダのデータベース、または異なるデータベースエンジン間の移行など幅広くサポートしており、いくつかの設定をクリックするだけで移行が簡単に行えます。
主な機能や特徴については公式のドキュメントをご参照ください。

移行方法

事前準備

移行元のデータベースを CloudSQL で用意します。
今回はサンプルデータベースとして入れた、world_db を移行対象のデータとします。
構成は長くなるので一部抜粋し、以下の観点を確認します。

  • レコード数
mysql> SELECT COUNT(*) FROM country;
+----------+
| COUNT(*) |
+----------+
|      239 |
+----------+
1 row in set (0.03 sec)

mysql> SELECT COUNT(*) FROM city;
+----------+
| COUNT(*) |
+----------+
|     4079 |
+----------+
1 row in set (0.04 sec)

mysql> SELECT COUNT(*) FROM countrylanguage;
+----------+
| COUNT(*) |
+----------+
|      984 |
+----------+
1 row in set (0.04 sec)
  • テーブル情報
mysql> desc country;
+----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+
| Field          | Type                                                                                  | Null | Key | Default | Extra |
+----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+
| Code           | char(3)                                                                               | NO   | PRI |         |       |
| Name           | char(52)                                                                              | NO   |     |         |       |
| Continent      | enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') | NO   |     | Asia    |       |
| Region         | char(26)                                                                              | NO   |     |         |       |
| SurfaceArea    | decimal(10,2)                                                                         | NO   |     | 0.00    |       |
| IndepYear      | smallint                                                                              | YES  |     | NULL    |       |
| Population     | int                                                                                   | NO   |     | 0       |       |
| LifeExpectancy | decimal(3,1)                                                                          | YES  |     | NULL    |       |
| GNP            | decimal(10,2)                                                                         | YES  |     | NULL    |       |
| GNPOld         | decimal(10,2)                                                                         | YES  |     | NULL    |       |
| LocalName      | char(45)                                                                              | NO   |     |         |       |
| GovernmentForm | char(45)                                                                              | NO   |     |         |       |
| HeadOfState    | char(60)                                                                              | YES  |     | NULL    |       |
| Capital        | int                                                                                   | YES  |     | NULL    |       |
| Code2          | char(2)                                                                               | NO   |     |         |       |
+----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+
15 rows in set (0.04 sec)

mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int      | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int      | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.04 sec)

mysql> desc countrylanguage;
+-------------+---------------+------+-----+---------+-------+
| Field       | Type          | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| CountryCode | char(3)       | NO   | PRI |         |       |
| Language    | char(30)      | NO   | PRI |         |       |
| IsOfficial  | enum('T','F') | NO   |     | F       |       |
| Percentage  | decimal(4,1)  | NO   |     | 0.0     |       |
+-------------+---------------+------+-----+---------+-------+
4 rows in set (0.04 sec)

DMS 設定

1. 移行ジョブの概要

まず初めに基本情報を入力します。
本番稼働中などの条件があれば継続的な移行を検討する必要もあるかと思いますが、今回は検証なので1回限りで実施します。

  • 名前 / ID
  • 移行元データベース エンジン
  • リージョン
  • 移行ジョブの種類(継続的 or 1回限り)

2. 移行元の定義

続いて移行元データベースの接続情報を接続プロファイルに定義します。
接続プロファイルは事前に作成しておくことも可能ですが、ない場合はその場で作成できます。

接続プロファイルでは以下の情報を入力します。
検証なので root ユーザーを使っていますが、root の使用を避けたい場合は事前に移行用ユーザを作成します。
また、プライベート IP を使用しているため暗号化はなしとしましたが、セキュリティをより高めたい場合は指定可能です。

 

3. 移行先インスタンスの作成

次に移行先の CloudSQL インスタンスを作成します。
ここで今回の目的である「Enterprise Plus エディション」を選択します。

下へスクロールし、その他の項目も入力していきます。

4. 接続方法の選択

移行先 CloudSQL が作成されるまで数分かかるので、その間に次のステップへ。
ここでは、移行先データベースが移行元データベースへ接続する方法を選択します。
今回はプライベート IP を使った VPC ピアリングで接続します。

移行先 CloudSQL が作成されたら次へ進むことができます。
ちなみに、CloudSQL の画面だとリードレプリカとして以下のように作成されていました。
IP は移行元とは別になるため注意が必要です。

5. 移行ジョブのテスト

最後に設定項目を見直して問題なければ、移行ジョブのテストを行います。

テストが正常に完了すると以下のように表示されます。

以上で DMS の設定は完了です!
ジョブを作成して開始することで移行が始まります。

移行データの確認

移行中は対象ジョブのステータスで進行度を確認できます。(各ステータスについてはこちら
ステータスが「完了」となったら移行完了です。

CloudSQL もリードレプリカではなくなっていることが確認できました。

肝心のデータですが、差異なく移行できていることが確認できました!
確認観点としていた部分以外も問題ありませんでした。

  • レコード数
mysql> SELECT COUNT(*) FROM country;
+----------+
| COUNT(*) |
+----------+
|      239 |
+----------+
1 row in set (0.03 sec)

mysql> SELECT COUNT(*) FROM city;
+----------+
| COUNT(*) |
+----------+
|     4079 |
+----------+
1 row in set (0.04 sec)

mysql> SELECT COUNT(*) FROM countrylanguage;
+----------+
| COUNT(*) |
+----------+
|      984 |
+----------+
1 row in set (0.04 sec)
  • テーブル情報
mysql> desc country;
+----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+
| Field          | Type                                                                                  | Null | Key | Default | Extra |
+----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+
| Code           | char(3)                                                                               | NO   | PRI |         |       |
| Name           | char(52)                                                                              | NO   |     |         |       |
| Continent      | enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') | NO   |     | Asia    |       |
| Region         | char(26)                                                                              | NO   |     |         |       |
| SurfaceArea    | decimal(10,2)                                                                         | NO   |     | 0.00    |       |
| IndepYear      | smallint                                                                              | YES  |     | NULL    |       |
| Population     | int                                                                                   | NO   |     | 0       |       |
| LifeExpectancy | decimal(3,1)                                                                          | YES  |     | NULL    |       |
| GNP            | decimal(10,2)                                                                         | YES  |     | NULL    |       |
| GNPOld         | decimal(10,2)                                                                         | YES  |     | NULL    |       |
| LocalName      | char(45)                                                                              | NO   |     |         |       |
| GovernmentForm | char(45)                                                                              | NO   |     |         |       |
| HeadOfState    | char(60)                                                                              | YES  |     | NULL    |       |
| Capital        | int                                                                                   | YES  |     | NULL    |       |
| Code2          | char(2)                                                                               | NO   |     |         |       |
+----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+
15 rows in set (0.04 sec)

mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int      | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int      | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.04 sec)

mysql> desc countrylanguage;
+-------------+---------------+------+-----+---------+-------+
| Field       | Type          | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| CountryCode | char(3)       | NO   | PRI |         |       |
| Language    | char(30)      | NO   | PRI |         |       |
| IsOfficial  | enum('T','F') | NO   |     | F       |       |
| Percentage  | decimal(4,1)  | NO   |     | 0.0     |       |
+-------------+---------------+------+-----+---------+-------+
4 rows in set (0.04 sec)

終わりに

既存の CloudSQL Enterprise エディションから、Enterprise Plus エディションへの移行を行いました。
当初はデータベースの移行が必要と聞いてハードルが高そうなイメージがあったので、DMS を使用することで簡単に移行を行うことができました。
エディション間の切り替えができるアップデートを待つのも一つの手ですが、場合によってはこの方法で早めに Enterprise Plus エディションへ移行して、運用面のメリットを得るといった選択肢も十分考えられます。

参考:
Database Migration Service を使用してデータベースを Cloud SQL for MySQL に移行する
Cloud SQL Enterprise Plus エディションを発表:新エディションでは MySQL のパフォーマンスが最大 3 倍に向上