- 移行先のRDSを用意
- メンテナンスを入れて非RDSへの書き込みがなくなるようにする
- 非RDSからmysqldump
- mysqldumpしたデータをRDSへ投入
- 利用するDBをRDSに切り替え
- 動作確認
- メンテナンス解除
といった具合ですが、データベースに格納されているデータが大きいとメンテナンス時間は長時間に及びます
mysqldumpした後のデータサイズが約40GBの状態で試算してみると
mysqldumpに1時間、投入に3時間ぐらいは掛かりそうな雰囲気でした
これだけ長時間になるとサービスに与える影響が大きいなぁということで、いろいろと調べていてたどり着いたのがこの方法
- 非RDSからmysqldump
- 移行先のRDSを用意
- mysqldumpしたデータをRDSへ投入
- RDSを非RDSをマスターとしてレプリケーションするように設定
- メンテナンスを入れて非RDSへの書き込みがなくなるようにする
- RDSのレプリケーション設定を解除して、マスターモードで稼働するよう設定
- 利用するDBをRDSに切り替え
- 動作確認
- メンテナンス解除
この方法ならば、長時間に及ぶ作業はメンテナンス前に実施してしまい
メンテナンス中に行う作業は短時間の作業のみにできます
1時間もあれば十分な感じです
具体的な方法は次の通り
1.RDS Parameter Groupを3つ準備(デフォルトから変更するパラメータのみ記載)
・データ投入向け RDS Parameter Group
- autocommit=0
- innodb_flush_log_at_trx_commit=0
- innodb_support_xa=0
- character-set-client-handshake=0
- character_set_client=utf8
- character_set_connection=utf8
- character_set_database=utf8
- character_set_filesystem=utf8
- character_set_results=utf8
- character_set_server=utf8
- innodb_flush_log_at_trx_commit=0
- character-set-client-handshake=0
- character_set_client=utf8
- character_set_connection=utf8
- character_set_database=utf8
- character_set_filesystem=utf8
- character_set_results=utf8
- character_set_server=utf8
- innodb_flush_log_at_trx_commit=2
- character-set-client-handshake=0
- character_set_client=utf8
- character_set_connection=utf8
- character_set_database=utf8
- character_set_filesystem=utf8
- character_set_results=utf8
- character_set_server=utf8
2.RDS起動
5.5系なら5.5.33以降、5.6系なら5.6.13以降を選択
データ投入向けRDS Parameter Groupを選択
binlogを出力しないよう設定(Enabled Automatic BackupsをNoに設定)
Multi AZ=No
3.非RDSでmysql binlogが出力されるよう設定
/etc/my.cnfに以下を設定してrestart
- [mysqld]
- log-bin=mysql-bin
- expire_logs_days=7
4.非RDSでレプリケーション用ユーザ作成
- mysql> grant all on *.* to replicator identified by 'password';
- Query OK, 0 rows affected (0.09 sec)
- mysql> flush privileges;
- Query OK, 0 rows affected (0.04 sec)
5.非RDSの3306ポートにRDSから接続できるようFWやセキュリティグループを設定
6.既存DBから、フルダンプをファイルに書き出しつつRDSに投入
(投入速度をあげるために、ユニークキー、外部キーのチェックをOFFにしている)
- $ (echo "SET unique_checks=0;SET foreign_key_checks=0;"; mysqldump --order-by-primary --add-drop-table --add-locks --master-data=2 --quick --all-databases -udbuser -p) | tee /mnt/storage/dump.sql | mysql -f -urdbuser -p -h xxx.yyy.ap-northeast-1.rds.amazonaws.com database_name
待つこと数時間…
7.書き出したファイルからbinlogのファイル名とポジションを確認
- $ grep -m 1 MASTER_LOG /mnt/storage/dump.sql
- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000242', MASTER_LOG_POS=24812749;
8.RDSでレプリケーションの設定
- CALL mysql.rds_set_external_master('10.xxx.xxx.xxx',3306,'replicator','password','mysql-bin.000242',24812749,0);
- Query OK, 0 rows affected (0.11 sec)
- CALL mysql.rds_start_replication;
- +-------------------------+
- | Message |
- +-------------------------+
- | Slave running normally. |
- +-------------------------+
- 1 row in set (1.05 sec)
- Query OK, 0 rows affected (1.05 sec)
9.RDSでレプリケーションステータスの確認
- mysql> show slave status \G
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- Seconds_Behind_Master: 11069
10.念のためマスター側(非RDS)の方でもプロセスを確認
- mysql> show processlist;
- | 123 | replicator | ip-10-xxx-xxx-xxx.ap-northeast-1.compute.internal:57028 | NULL | Binlog Dump | 77 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL
このあたりが確認できれば接続はOK
あとは、マスターDBからの遅延時間
Seconds_Behind_Master: 11069
が0になってくれるまで待機
11.待っている間にレプリケーション中にエラーが起きた場合は、内容を確認してスキップするなどして対処する
- mysql> CALL mysql.rds_skip_repl_error;
- +-------------------------------------+
- | Message |
- +-------------------------------------+
- | Statement in error has been skipped |
- +-------------------------------------+
- 1 row in set (0.04 sec)
- +---------------------------+
- | Message |
- +---------------------------+
- | Slave is running normally |
- +---------------------------+
- 1 row in set (2.05 sec)
- Query OK, 0 rows affected (2.05 sec)
12.Enabled Automatic BackupsをYesに設定
- Modifyして1日以上に設定
13.マスター稼働用のパラメータグループに変更
14.RDSをマスターモードに切り替え
- mysql> CALL mysql.rds_stop_replication;
- +---------------------------+
- | Message |
- +---------------------------+
- | Slave is down or disabled |
- +---------------------------+
- 1 row in set (1.08 sec)
- Query OK, 0 rows affected (1.08 sec)
- mysql> CALL mysql.rds_reset_external_master;
- +----------------------+
- | message |
- +----------------------+
- | Slave has been reset |
- +----------------------+
- 1 row in set (0.18 sec)
- Query OK, 0 rows affected (0.18 sec)
ここまで来たら、あとは動作確認して終了ヾ(*・∀・)ノ"
0 件のコメント:
コメントを投稿