- 移行先の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・レプリケーション向けRDS Parameter Group
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・本番運用向けRDS Parameter Group
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 | NULLRDSから接続が来ていますね
このあたりが確認できれば接続は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 件のコメント:
コメントを投稿