まめ畑

ゆるゆると書いていきます

EC2・オンプレ環境のMySQLからRDSのマイグレーションがやりやすくなった

本日
Migrate On-Premises MySQL Data to Amazon RDS (and back) | AWS Official Blog
Importing Data to an Amazon RDS MySQL DB Instance with Reduced Downtime - Amazon Relational Database Service
の発表があり、RDSに対して、オンプレミス環境・EC2上で動いているMySQLとのマイグレーションが行い易くなりました。

ただ、常にレプリケーションさせてというわけではなく、移行時に使うという用途です。

オンプレミス環境・EC2上で動いているMySQLとRDSでレプリケーションが可能になりました。
ドキュメントには環境・データサイズ毎のマイグレーションについて書かれているのでご一読下さい。

つまり
f:id:con_mame:20130906121306p:plain
このような構成が取れるようになりました。


RDS(MySQL5.6) -> EC2・オンプレ上のMySQLにもレプリケーションが可能です。
Using Replication to Export MySQL 5.6 Data - Amazon Relational Database Service
をご参照ください。手順は一般的なレプリケーションの設定と同じですが、Security Groupで接続元の開放が必要です。


簡単に試してみたので書いておきます。

こちらを使うことでDBをRDSに移行したいというときに、今までだと、サービスや書き込みを停止させ、dump -> importを行ってと時間がかかりましたが、バックアップなどからRDSを作成し、レプリケーションを追い付かせて、接続先の変更だけを行なうだけで良くなるので、サービスなどを止める時間を大幅に軽減出来ます。

制限

現在RDSでこの機能に対応しているMySQLのバージョンは

  • 5.5.33
  • 5.6.13

のみです。

他のバージョンではストアード・プロシージャーが入っていません。
現在のMySQLの最新版のみという感じです。

RDSはGTIDをONに出来ないので、GTID modeは有効に出来ません。

設定方法

通常のレプリケーションを組むのとあまり変わりは無いですが、

なのですが、RDSでレプリケーションの設定に関しては、通常のCHANGE MASTERやSTART / STOP SLAVEが使えません。
これらは用意されているストアード・プロシージャーを使用します。

 GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.%' IDENTIFIED BY 'slavepass';

接続元のIPアドレスは、VPC内であればRDSが所属しているサブネットのIPアドレスになります。

  • dump / impot
mysqldump -uhoge -p DB | mysql -hrds-database.xxxxxx.ap-northeast-1.rds.amazonaws.com -uhogehoge -pfugafuga -DDB

という感じで流し込めます。

もしくは一旦dumpしてなど。

サイズの大きなDBをimportする際は、一時的にRDSのパラメータグループで、innodbトランザクションやコミット周りの設定を変更しておくことでimportの時間が速くなりますが、安全ではないので、必ずもとに戻しておきます。
時間があるのであればそのままimportで問題ないです。

この時にmasterのbinlog名とポジションを控えておきます。

  • RDS側

mysql.rds_set_external_master - Amazon Relational Database Service
ここがRDS特有なのですが、CHANGE MASTERなどは権限がないためストアード・プロシージャーを使用します。

call mysql.rds_set_external_master('接続先DBのIPアドレス or FQDN',PORT,'USER','PASS','Binlog name',position,0);

最後の0はSSLを使うかどうかです、default 0は使用しない。1で使用する。

成功すると何も出てこないですが、

SHOW SLAVE STATUS;

レプリケーションの状態を確認します。

start / stop slaveは

call mysql.rds_start_replication;

を実行します

+-------------------------+
| Message                 |
+-------------------------+
| Slave running normally. |
+-------------------------+
1 row in set (1.04 sec)

このような感じでエラーがなければレプリケーションが開始されます。

stopは

call mysql.rds_stop_replication;
+---------------------------+
| Message                   |
+---------------------------+
| Slave is down or disabled |
+---------------------------+
1 row in set (1.02 sec)

となっています。


レプリケーションを解除する場合は

call mysql.rds_reset_external_master;

を実行します。
これは、内部でstop slaveとreset slave allを実行しています。

ストアード・プロシージャーの中身が気になる方は

show create procedure mysql.rds_set_external_master;

で見れます。

おまけ

現在

  • 5.5.33
  • 5.6.13

をストアード・プロシージャーが増えており

+-------+-----------------------------------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db    | Name                              | Type      | Definer            | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+-------+-----------------------------------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| mysql | rds_collect_global_status_history | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_disable_gsh_collector         | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_disable_gsh_rotation          | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_enable_gsh_collector          | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_enable_gsh_rotation           | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_external_master               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_kill                          | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_kill_query                    | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_next_master_log               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_reset_external_master         | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_rotate_general_log            | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_rotate_global_status_history  | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_rotate_slow_log               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_configuration             | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_external_master           | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_gsh_collector             | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_gsh_rotation              | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_show_configuration            | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_skip_repl_error               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_start_replication             | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_stop_replication              | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
+-------+-----------------------------------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+

となっております。

対応していないバージョンのMySQLをRDSで使っている場合は、ModifyからバージョンをUpdateしたタイミングで作成されます。


レプリケーションを操作したログは

 select * from mysql.rds_history;
+---------------------+-----------------------+-------------------+---------------+--------------+-------------+--------------+------------------+----------------+------------+
| action_timestamp    | called_by_user        | action            | mysql_version | master_host  | master_port | master_user  | master_log_file  | master_log_pos | master_ssl |
+---------------------+-----------------------+-------------------+---------------+--------------+-------------+--------------+------------------+----------------+------------+
| 2013-09-06 01:49:01 | rdsadmin@localhost    | enable set master | 5.6.13        | NULL         |        NULL | rdsrepladmin | NULL             | NULL           |       NULL |
| 2013-09-06 01:58:57 | hogehoge@xxx.xxx.xxx.xxx | set master        | 5.6.13        | xxx.xxx.xxx.xxx |        3306 | repl         | mysql-bin.000001 | 1061           |          0 |
| 2013-09-06 01:59:30 | hogehoge@xxx.xxx.xxx.xxx | start slave       | 5.6.13        | NULL         |        NULL | NULL         | NULL             | NULL           |       NULL |
| 2013-09-06 01:59:55 | hogehoge@xxx.xxx.xxx.xxx | stop slave        | 5.6.13        | NULL         |        NULL | NULL         | NULL             | NULL           |       NULL |
| 2013-09-06 02:00:55 | hogehoge@xxx.xxx.xxx.xxx | start slave       | 5.6.13        | NULL         |        NULL | NULL         | NULL             | NULL           |       NULL |
+---------------------+-----------------------+-------------------+---------------+--------------+-------------+--------------+------------------+----------------+------------+

このテーブルに追加されていきます。

レプリケーションの状態は

select * from mysql.rds_replication_status;
+---------------------+-----------------------+-------------+---------------+--------------+-------------+
| action_timestamp    | called_by_user        | action      | mysql_version | master_host  | master_port |
+---------------------+-----------------------+-------------+---------------+--------------+-------------+
| 2013-09-06 04:26:32 | hogehoge@xxx.xxx.xxx.xxx | start slave | 5.6.13-log    | xxx.xxx.xxx.xxx |        3306 |
+---------------------+-----------------------+-------------+---------------+--------------+-------------+

を事項すると状態がとれます。

レプリケーションのエラーが起こった場合は、

call mysql.rds_skip_repl_error

でSET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;が実行されます。

レプリケーションのエラーは
f:id:con_mame:20130906134319p:plain
とManagement Consoleにも表示されます。

こういうのも出来ます

EC2やオンプレDB -> RDS -> ReadReplica

こちらは、上記の手順でレプリケーションを組んだ後にRRを作成するだけです。
f:id:con_mame:20130906121303p:plain

まとめ

RDSへのマイグレーションが今までよりも行いやすくなりました。サイズの大きなDBのdumpデータをS3にuploadして、S3から直接import出来ると便利だなぁと思いました。

しかし、あくまでマイグレーション用かなという感じで、Multi-AZ配置した場合にfailoverが行わた時や、Promoted Readreplicaについてはまだ検証していませんが、接続元のIPアドレスも変わりますし、レプリケーション情報も同期されていないと思うので、通常用途では検証の余地があるかと思います。
一時的に集計などで使う場合に簡単に状況に応じてスペックが変えやすいので、そういう場合は常にレプリケーションさせて置いていいかもしれません。

また、replicate-do-dbは設定出来ないので、既存のDBの一部テーブル・DBだけを移行用にレプリケーションというのが出来ないので、これが出来るようになると更に便利になるかと思います。