そろばんのしょ(第3版第2刷)

雑魚い見習いDBAの日々学んだことや、どーでもいいことを。基本は自分の備忘録。

mysqlのバージョンが古くてdump-slaveオプションが使えない時の対処法

これは 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)

  1. trm1でFLUSH TABLES WITH READ LOCKをかけてテーブルロックをかける
trm1> FLUSH TABLES WITH READ LOCK;
  1. 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)
  1. trm2でdumpを開始
$ /usr/local/mysql/bin/mysqldump --socket=/tmp/mysql.sock -uroot -p'****' > /tmp/dump.sql
  1. 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)
  1. unlock tables;でロックを解除
trm1> unlock tables;
  1. 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が使えないと知った時はどうやってやるのか検討もつかなかったので無事作成できて何よりです。