AWS
RDS
mysql5.7

RDS からEC2へ Multi-master replicationを組んでみた

More than 1 year has passed since last update.

この記事はRetty Inc. Advent Calendar 2017 15日目の記事です。
昨日は @isaoeka さんによる OS X アプリケーション(Today Extension)開発に触れてみる でした。

こんにちは、Rettyでインフラを担当している@takumi-suzukiです。
7月から宮城でリモート勤務をしていて、11月から東京に帰ってきました。
東京はamazonで注文したものが翌日には届いて最高です。

今回は、MySQLを調べていて興味をもったMulti-master replicationについて書きます。
業務でも活かせるように、AWSのRDSを使用していたものから、EC2にレプリケーションを貼ります。

使用したサーバー

  1. Master DB01 (RDS MySQL 5.7.19)
  2. Master DB02 (RDS MySQL 5.7.19)
  3. Replica DB01(EC2 AmazonLinux2)

ReplicaDB の準備

最近リリースされた、AmazonLinux 2にMySQL 5.7をインストールして使用します。

MySQL5.7のインストール

AmazonLinuxで通常通り yum install mysql とかとやってしまうと、MariaDBが入ってしまうので、以下の方法でMySQLをインストールします。

# リポジトリ追加
$ sudo yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm

# 確認
$ yum info mysql-community-server

# インストール
$ sudo yum -y install mysql-community-server

[ec2-user@ip-172-22-246-193 ~]$ mysqld --version
mysqld  Ver 5.7.20 for Linux on x86_64 (MySQL Community Server (GPL))
[ec2-user@ip-172-22-246-193 ~]$

# 自動起動設定
$ sudo systemctl enable mysqld.service

# 起動
$ sudo systemctl start mysqld.service

MySQL5.7の初期設定

MySQL5,7ではポリシーでMEDIUMが設定されているため、パスワードが厳し目に設定しなければいけません。
テスト的にやりたいのに、そんなパスワードは設定したくないため、以下の方法でポリシーを変更し、パスワード変更を行います。

# パスワード設定しないと諸々変更できないので、とりあえずのパスワードを設定します。
> set password for root@localhost=password('PassWord@0123456789');

# パスワードポリシーの変更
> SET GLOBAL validate_password_length=4;
> SET GLOBAL validate_password_policy=LOW;

# パスワード変更
> set password for root@localhost=password('root');

my.cnfの設定

replicationが組めるように、以下の設定を追記します。

server-id=1024
relay_log_info_repository = TABLE
master_info_repository = TABLE
relay_log_recovery = ON

mysqlを再起動します
sudo systemctl restart mysqld.service

レプリケーション設定

ここから、RDSとEC2でレプリケーションを組んでいきます。

Master にReplication Userを作成

replication を組むためのuserをMasterとなるそれぞれのDBに対して作成します。

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

Master情報の確認

replicationを組むためにのmasterのLogとポジションを調べます。

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin-changelog.000021
         Position: 154
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.03 sec)

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin-changelog.000021
         Position: 154
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.03 sec)

Replication 開始

Master情報をReplicaDBに設定します

> CHANGE MASTER TO
  MASTER_HOST='master01.********.ap-northeast-1.rds.amazonaws.com',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin-changelog.000021',
  MASTER_LOG_POS=154,
  MASTER_CONNECT_RETRY=10
  for channel 'master01';

> CHANGE MASTER TO
  MASTER_HOST='master02.********.ap-northeast-1.rds.amazonaws.com',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin-changelog.000022',
  MASTER_LOG_POS=154,
  MASTER_CONNECT_RETRY=10
  for channel 'master02';

以下のコマンドでReplicationを開始します。

start slave for channel 'master01';
start slave for channel 'master02';

確認

以下のようにして、それぞれのMasterとのreplicationが確立されているかを確認します。

mysql> mhow slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: test-master01.ckudyu9ubkf5.ap-northeast-1.rds.amazonaws.com
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mysql-bin-changelog.000046
          Read_Master_Log_Pos: 521
               Relay_Log_File: ip-172-22-246-193-relay-bin-master1.000050
                Relay_Log_Pos: 754
        Relay_Master_Log_File: mysql-bin-changelog.000046
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 521
              Relay_Log_Space: 1038
              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: 1940910623
                  Master_UUID: 2a111330-e15e-11e7-8d0e-0a57ab429cea
             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 more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: master1
           Master_TLS_Version: 
*************************** 2. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: test-master02.ckudyu9ubkf5.ap-northeast-1.rds.amazonaws.com
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mysql-bin-changelog.000045
          Read_Master_Log_Pos: 154
               Relay_Log_File: ip-172-22-246-193-relay-bin-master2.000050
                Relay_Log_Pos: 387
        Relay_Master_Log_File: mysql-bin-changelog.000045
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 671
              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: 1018574732
                  Master_UUID: bdeace00-e15e-11e7-b0c2-067018182636
             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 more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: master2
           Master_TLS_Version: 
2 rows in set (0.00 sec)

テスト

master01とmaster02にINSERTを行い、ReplicaDBに反映されるかを確認します。

master1
mysql> INSERT INTO item (id,name) VALUES (1,"master1");
Query OK, 1 row affected (0.04 sec)

mysql> INSERT INTO item (id,name) VALUES (4,"master1");
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM item
    -> ;
+------+---------+
| id   | name    |
+------+---------+
|    1 | master1 |
|    4 | master1 |
+------+---------+
2 rows in set (0.04 sec)
master2
mysql> INSERT INTO item (id,name) VALUES (2,"master2");
Query OK, 1 row affected (0.04 sec)

mysql> INSERT INTO item (id,name) VALUES (3,"master22");
Query OK, 1 row affected (0.05 sec)

mysql> SELECT * FROM item ;
+------+---------+
| id   | name    |
+------+---------+
|    2 | master2 |
|    3 | master2 |
+------+---------+
2 rows in set (0.05 sec)

mysql> 
replicaDB
mysql> SELECT * FROM item;
+------+---------+
| id   | name    |
+------+---------+
|    2 | master2 |
|    3 | master2 |
|    1 | master1 |
|    4 | master1 |
+------+---------+
4 rows in set (0.00 sec)

mysql>

無事反映されてることを確認できました。

まとめ

最近のタスクでDB周りをやっていて、RDS周りで調査がスムーズにできないために外だししたくて試してみました。
思ったほど、癖があるわけではなくすんなりとレプリケーションを組むことができました。
しかし、検証環境や調査環境で使う分にはいいですが、本番はあまり使いたくないなと思っている所存です!!

明日は captain( @takaaki-suzuki ) の NVIDIA DGX Station を試してみた です。お楽しみに〜