okochangの馬鹿でありがとう

ふらふら適当に世間を生きる日々でございます

東京リージョンのRDSからシンガポールリージョンのRDSにレプリケーションをしてみる

こんにちは@oko_changです。
少し前の話になりますが、オンプレミスのMySQLからRDSへ、RDSからオンプレミスのMySQLレプリケーションを行うことが出来るようになりました。

Amazon Web Services ブログ: 【AWS発表】 オンプレミスのMySQLデータをAmazon RDSへ移行する(その逆も)

ということはRDSからRDSへのレプリケーションも出来そうというなので、試してみました。
あ、RDSを使えばReadReplicaで簡単にレプリケーション構成を組む事が出来ますよ!

※11/15(金)追記:クロスリージョンのリードレプリカが発表されました
[速報]Amazonクラウド、データベースを地理分散する「Amazon RDS Cross-Region Read Replicas」「Redshift Snapshot Copy」発表。ディザスタリカバリを容易に。AWS re:Invent 2013 - Publickey

構成図

同一リージョンであればそれこそReadReplicaでOKなので、東京リージョンのRDSからシンガポールリージョンのRDSにレプリケーションを行います。

f:id:okochang:20131108001848p:plain

環境

東京リージョンとシンガポールリージョンにそれぞれ以下の環境を用意します。

  • MySQL5.6.13のRDS
  • Publicly AccessibleをON
  • Mullti-AZオプションはOFF
  • セキュリティグループではお互いの通信を許可
  • マスターのRDSからスレーブのRDSへダンプ/インポート出来る環境

ダンプ/インポートが出来る環境の用意

もし手元でmysqldumpが実行出来る環境がなければ以下のように用意します。
※以下はAmazon Linuxの例です

$ wget \
http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.6/MySQL-client-5.6.14-1.el6.x86_64.rpm \
http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.6/MySQL-shared-5.6.14-1.el6.x86_64.rpm \
http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.6/MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm \
http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.6/MySQL-devel-5.6.14-1.el6.x86_64.rpm
$ sudo rpm -ivh MySQL-client-5.6.14-1.el6.x86_64.rpm \
MySQL-devel-5.6.14-1.el6.x86_64.rpm \
MySQL-shared-5.6.14-1.el6.x86_64.rpm \
MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm 

検証手順

マスター(東京)RDSの設定

レプリケーションユーザーを作成します。

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

検証用のDBとテーブルを作って適当にデータを入れておきます。

create database okochangdb;
use okochangdb;
create table t1 (id int, dep int, name char(30), comment char(100)) character set utf8;
insert into t1 values (1, 1, 'cat', 'good');
insert into t1 values (2, 2, 'dog', 'cute');

RDSのバイナリログにアクセスを出来るようにするため以下のストアドプロシージャを実行します。

call mysql.rds_set_configuration('binlog retention hours', 72);

マスターのログファイル名とPositionをメモしておきます。

show master status;
+----------------------------+----------+--------------+------------------+-------------------+
| File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-changelog.000298 |      422 |              |                  |                   |
+----------------------------+----------+--------------+------------------+-------------------+
スレーブ(シンガポール)のDSの設定

レプリケーションユーザーを作成します

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'slavepass';
データ投入

マスターのRDSからスレーブのRDSへデータベースをdump/importします

$ mysqldump -h okochang-master.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u root -p --databases okochangdb \
| mysql -h okochang-slave.yyyyyyyyyyyy.ap-southeast-1.rds.amazonaws.com -u root -p
レプリケーションをする

スレーブ側のRDSで以下のストアドプロシージャを実行します。
※先ほどメモしたログファイル名とPositionなどはそれぞれ置き換えて下さい

call mysql.rds_set_external_master('okochang-master.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com',3306,'repl','slavepass','mysql-bin-changelog.000298',422,0);

さらに以下のストアドプロシージャを実行してレプリケーションを開始します。

CALL mysql.rds_start_replication;
動作確認

レプリケーションが始まっていることを確認します。

show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: okochang-master.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-changelog.000299
          Read_Master_Log_Pos: 422
               Relay_Log_File: relaylog.000005
                Relay_Log_Pos: 595
        Relay_Master_Log_File: mysql-bin-changelog.000299
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: mysql.plugin,innodb_memcache.config_options,innodb_memcache.cache_policies,mysql.rds_replication_status,mysql.rds_history
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 422
              Relay_Log_Space: 818
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 887634328
                  Master_UUID: 4cd4e873-4561-11e3-8746-020fec01a218
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0

マスタ側のRDSでレコードを追加してみます。

use okochangdb;
insert into t1 values (3, 3, 'hoge', 'fuga');

スレーブ側のRDSでレコードが追加されていることを確認します。

use okochangdb
select * from t1;
+------+------+-------+--------------+
| id   | dep  | name  | comment      |
+------+------+-------+--------------+
|    1 |    1 | cat   | good         |
|    2 |    2 | sari  | cute         |
|    3 |    3 | hoge  | fuga         |
+------+------+-------+--------------+

まとめ

当然といえば当然ですが、RDSからRDSへのレプリケーションを行うことが出来ました。
とはいReadReplicaを作る方が圧倒的に簡単ですね。
また、Publicly AccessibleでRDSに割り当てられているグローバルIPが変わった場合を考えるとセキュリティグループのルールが悩ましいです。
というわけで、参考程度に、やる場合は自己責任でお願いします。