Aurora のクローン機能を使った VPC 移行を試してみた

Posted on

長年 AWS を使っているとさまざまな理由で VPC を移行したくなるときが来ます。例えば、サービスが成長して Subnet の IP アドレスが足りなくなったり、セキュリティ要件を満たすために Subnet の設計を変えたい、などなど。

Disposable Components な設計を心がけていれば EC2 を移行するのはそれほど難しくありません。移行が難しいのは RDS です。

RDS を VPC 移行するには、書き込みをすべて止めてから Snapshot を取得し、その Snapshot を元に新しい VPC で RDS インスタンスを起動するのが一般的です(異なる VPC に Read Replica を作ることができないため、Read Replica を昇格させる方法は使えない)。ただ、この方法だとメンテナンスに切り替えてから Snapshot を取るため、データ量によっては長時間のメンテナンスが必要になります。

Database Migration Service を使ってレプリケーションする手もありますが、今回は Aurora のクローン機能を使って VPC 移行する方法を検証してみました。この方法だと数分で移行することができます。

Aurora のクローン機能とは

Aurora DB クラスターでのデータベースのクローン作成」から引用します。

データベースのクローンを使用すると、すべてのデータベースのクローンを迅速かつ高いコスト効率で作成できます。クローンデータベースの初回作成時に必要な追加スペースは最小限です。データベースのクローン作成で使用されるコピーオンライトプロトコルでは、ソースデータベースまたはクローンデータベースのいずれかでそのときに変更されたデータがコピーされます。

Aurora の分散ストレージを活用した機能で、クローンを作成した時点では実際のデータはコピーされません。元になったデータベース、またはクローンされたデータベースで変更されたときに初めてデータをコピーします(これが Copy On Write プロトコル)。そのためクローンにかかる時間はクローン側の Aurora を起動する時間だけで済みます。

Copy On Write プロトコルの仕組みはドキュメントにあるこの図がわかりやすいです。

Aurora クローンの Copy On Write プロトコルの仕組み

クローンデータベースで変更がなければソースデータベースのストレージを参照しているだけなのでストレージ料金も増えません。これが高いコスト効率の理由です。

ソースデータベースとクローンデータベースはお互いに影響することはありません。例えば、クローンデータベースで DROP DATABASE してもソースデータベースには残っていますし、ソースデータベースの CPU や IOPS にも影響ありません。

また、クローンデータベースを起動するときに VPC を選択することができます。 EBS を使っている他の RDS では考えられないことですが、Aurora の分散ストレージのおかげで同じリージョンであれば参照できる仕組みになっているのでしょう。

このクローン機能を使って VPC 移行すれば、メンテナンス中にやることはクローンの作成とデータベースへの再接続だけです。 Snapshot を取得するやり方に比べれば圧倒的に短時間で終わらせられます。

実際に試してみた

仕組みは理解できたので実際に試してみました。ソースデータベースは testdb、クローンデータベースは testdb-clone という名前にしました。

まずは testdb で適当なデータを作ります。

$ mysql -h testdb.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u admin -p
(snip)

mysql> create database testdb;
Query OK, 1 row affected (0.01 sec)

mysql> use testdb;
Database changed

mysql> create table test(
    ->     id integer,
    ->     name varchar(64)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into `test` (id, name) values (1, 'foo');
Query OK, 1 row affected (0.01 sec)

mysql> insert into `test` (id, name) values (2, 'bar');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | foo  |
|    2 | bar  |
+------+------+
2 rows in set (0.01 sec)

この状態で Management Console からクローンを作成します。今回は VPC 移行が目的なので testdb とは違う VPC を選択します。

起動してきた testdb-clone のデータを確認してみると、たしかに testdb で作ったデータがあります。

$ mysql -h testdb-clone.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u admin -p
(snip)

mysql> use testdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | foo  |
|    2 | bar  |
+------+------+
2 rows in set (0.01 sec)

2 つのデータベースはもう別物になっているので、この状態で testdb にデータを作っても testdb-clone には反映されません。

最後に testdb-clone にコネクションを張ったまま testdb を削除してみましたが、コネクションは維持されたままで testdb で作ったデータも残っています。

mysql> select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | foo  |
|    2 | bar  |
+------+------+
2 rows in set (0.01 sec)

まとめ

Aurora のクローン機能を使えば最小のメンテナンス時間で VPC 移行できることがわかりました。 VPC を移行することは滅多にないと思いますが、知っておいて損はないでしょう。

Aurora のクローン機能は他でもいろいろと活用できるシーンがありそうなので、引き続き検証してみようと思います。