これは MySQL Casual Advent Calendar 2017 の Day14 の記事です。
少し前にMySQL4.0を5.0にするという作業をしたときにmysqldumpでdump-slaveオプションが使えなかったときの話です。 世間ではMySQL8.0で賑わって?おりますが、このご時世4.0というバージョンを使っていたアプリケーションがありまして、とりあえず5.0にしようかという話になりました。 そこで5.0にするために事前に5.0のレプリケーションをmysqldumpを使って作ることにしました。
そのデータベースはアプリケーションで運用しているMasterのデータベースが1台と、バックアップ取得用としてレプリケーションを組んだデータベースが1台ありました。 mysqldumpには5.5からdump-slaveというオプションがありまして、このオプションを利用することでslaveのデータベースから、Masterのpositionを取得して"CHANGE MASTER TO"の中に埋め込むことができます。 しかし、5.5未満のバージョンにはこのプションがありません。
そこでFLUSH TABLES WITH READ LOCKをslave側に使ってmysqldumpを行うという技を利用して対処しました。
用意するもの:ターミナル2ウィンドウ(以下trm1,trm2)
- trm1で
FLUSH TABLES WITH READ LOCKをかけてテーブルロックをかける
trm1> FLUSH TABLES WITH READ LOCK;
- trm1で
show slave statusを実行し、dump取得直前のExec_master_log_posを確認
trm1 > show slave status\G
*************************** 1. row ***************************
Master_Host: 192.168.33.101
Master_User: replication
Master_Port: 3306
Connect_retry: 60
Master_Log_File: mysql-bin.8747
Read_Master_Log_Pos: 1018652977
Relay_Log_File: relay-bin.2679
Relay_Log_Pos: 363016692
Relay_Master_Log_File: mysql-bin.8747
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_do_db:
Replicate_ignore_db:
Last_errno: 0
Last_error:
Skip_counter: 0
Exec_master_log_pos: 1018652977
Relay_log_space: 363016692
1 row in set (0.00 sec)
- trm2でdumpを開始
$ /usr/local/mysql/bin/mysqldump --socket=/tmp/mysql.sock -uroot -p'****' > /tmp/dump.sql
- dump完了後trm1で
show slave statusでexec master log posが変更してないことを確認
trm1 > show slave status\G
*************************** 1. row ***************************
Master_Host: 192.168.33.101
Master_User: replication
Master_Port: 3306
Connect_retry: 60
Master_Log_File: mysql-bin.8747
Read_Master_Log_Pos: 1018652977
Relay_Log_File: relay-bin.2679
Relay_Log_Pos: 363016692
Relay_Master_Log_File: mysql-bin.8747
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_do_db:
Replicate_ignore_db:
Last_errno: 0
Last_error:
Skip_counter: 0
Exec_master_log_pos: 1018652977
Relay_log_space: 363016692
1 row in set (0.00 sec)
unlock tables;でロックを解除
trm1> unlock tables;
show slave statusでレプリケーションが再開していることを再確認する
trm1 > show slave status\G
*************************** 1. row ***************************
Master_Host: 192.168.33.101
Master_User: replication
Master_Port: 3306
Connect_retry: 60
Master_Log_File: mysql-bin.8747
Read_Master_Log_Pos: 1028503328
Relay_Log_File: relay-bin.2679
Relay_Log_Pos: 372867043
Relay_Master_Log_File: mysql-bin.8747
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_do_db:
Replicate_ignore_db:
Last_errno: 0
Last_error:
Skip_counter: 0
Exec_master_log_pos: 1028503328
Relay_log_space: 372867043
1 row in set (0.00 sec)
無事Masterのpositionを把握してdumpを取得することができました。あとは新Slaveにdumpを適用して"CHANGE MASTER TO"を打てば完了です。 長年MySQLを触っている方にとっては常套手段らしいですね。とはいえ、dumpslaveが使えないと知った時はどうやってやるのか検討もつかなかったので無事作成できて何よりです。