MySQLのレプリケーション遅延をローカルで再現させる手順 その2

こんにちは、株式会社CFlatです。
前回の続きです。

ローカルで立ち上げた2つのMySQLインスタンスをMaster-Slaveにする

[mysqld1]をMaster、[mysqld2]をSlaveにするための設定をしていきます。

/etc/my.cnfを書き換える

設定ファイルに2行を追加してMySQLを再起動します。

[mysqld_multi]
mysqld     = /usr/local/Cellar/mysql/5.6.10/bin/mysqld_safe
mysqladmin = /usr/local/Cellar/mysql/5.6.10/bin/mysqladmin
user       = multi
password   = password
log        = /usr/local/var/log/mysql_multi.log

[mysqld]

[mysqld1]
server-id = 101
user = root
port = 3306
datadir  = /usr/local/var/mysql
socket   = /tmp/mysql.sock
pid-file = /tmp/mysql.pid
log-bin = mysql-bin # 追加
binlog_format = mixed # 追加

[mysqld2]
server-id = 102
user = root
port = 3307
datadir  = /usr/local/var/mysql2
socket   = /tmp/mysql.sock2
pid-file = /tmp/mysql.pid2

再起動。

$ mysqld_multi stop
$ mysqld_multi start # restartが無いみたいですね…?
レプリケーション用のユーザーを作成する

MasterのログをSlaveに転送するとき、SlaveからMasterへの通信が起こります。そのときに使うためのユーザーを[mysqld1]に追加しておく必要があります。

$ mysql -u root -p
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@localhost IDENTIFIED BY 'repl'; # REPLICATION SLAVE権限だけ
MasterのデータをSlaveにコピーする

これまでもローカルのMySQLを使っていた場合Masterとなっているほうに入っているデータがあるはずです。レプリケーションを開始する前にマスターとスレーブのデータを同じにしておく必要がありますのでデータをコピーします。

まず、Masterのテーブルをロックします。

$ mysql -u root -p
mysql> FLUSH TABLES WITH READ LOCK;

次にMasterのデータをディレクトリの中身をSlaveのデータディレクトリにコピーします。

$ cp -aR /usr/local/var/mysql/* /usr/local/var/mysql2/

コピーしたファイルの中にMasterに関する情報が書かれているものがあるので、それを削除して再起動しておきます。

$ rm /usr/local/var/mysql2/auto.cnf
$ mysqld_multi stop
$ mysqld_multi start

コピーが終わったのでテーブルのロックを解除しておきます。

mysql> UNLOCK TABLES;
レプリケーションを開始する

これからSlaveでレプリケーションのための設定をするのですが、そのときに必要な情報を先にMasterで調べておきます。

$ mysql -u root -p
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |      107 |              |                  |
+------------------+----------+--------------+------------------+

FileとPosition両方が必要です。

次にSlaveにログインして設定を行います。

$ mysql -u root -p --socket/tmp/mysql.sock2

# FileとPositionは先程調べた値を使う
mysql> CHANGE MASTER TO MASTER_HOST= 'localhost',
       MASTER_USER='repl',
       MASTER_PASSWORD='repl',
       MASTER_LOG_FILE='mysql-bin.000003',
       MASTER_LOG_POS=107;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...

設定はこれで終わりなので動作確認。適当にデータベースを作ったりしてみます。

$ mysql -u root -p # Master
mysql> CREATE DATABASE aaaaaaaa;

$ mysql -u root -p --socket=/tmp/mysql.sock2 # Slave
mysql> SHOW DATABASES;

Masterで作ったデータベースがSlaveにも反映されているはず。これでレプリケーションはOKですね。

レプリケーションを遅延させる

percona-toolkitをインストール

percona-toolkitに含まれるpt-slave-delayというコマンドでレプリケーションを故意に遅延させられるらしいです。

$ sudo cpan -i DBD::mysql # percona-toolkitがPerlモジュールに依存しているらしい
$ brew install percona-toolkit 
遅延を発生させる

pt-slave-delayを使えるようになりました。pt-slave-delayはSlaveの開始と停止を繰り返すことで遅延を発生させます。

基本的な使い方は次のような感じです。

$ pt-slave-delay --delay 30s --interval 10s --socket=/tmp/mysql.sock2 -u root -p rootpassword localhost 

--delay が文字通り遅延させる秒数、--intervalが停止か開始かを判断する頻度、それ以降は接続するSlaveの情報です。

その他のオプションはこのページを参照のこと。
pt-slave-delay ― Percona Toolkit Documentation

ここまでで開発環境でもレプリケーションの遅延を発生させる準備ができました。
これで遅延が発生しても問題ない設計で開発を進めていくことができるようになりました。