Edited at

MySQLでわざとレプリケーションを遅延させる方法

More than 1 year has passed since last update.


概要

2016年11月17日のお話。

前回1台のサーバでレプリケーション設定をしました。

レプリケーションを想定した開発環境を作る事が目的なのですが、そうであればわざとレプリケーションを遅延させることで問題がちゃんと出るようにしておく必要があるかと思います。

遅延のさせ方はMySQL5.6以前と以降で大きく2通りありまして、それぞれ違っています。

MySQL5.6以降はどれだけ遅延させるかという設定がMySQL自体に備わっていますのでとても簡単に実現できますが、MySQL5.6より前になってしまうとそのような機能がありませんので、STOP SLAVEとSTART SLAVEを繰り返すことによって遅延しているような感じを作り出すスクリプトを使う事になります。


作業手順


MySQL5.6以降の場合

まずはMySQL5.6以降の場合の設定方法、前回のレプリケーション設定を行っている前提になります。

スレーブにアクセスしてCHANGE MASTERを行います。

この設定例の場合は、10秒遅延することになります。

$ mysql -u root -h 127.0.0.1 -P 3307 -p

mysql> STOP SLAVE;
Query OK, 0 rows affected (0.10 sec)

mysql> CHANGE MASTER TO MASTER_DELAY = 10;
Query OK, 0 rows affected (0.17 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.06 sec)

そして状態と遅延を確認します。

SQL_Delay: 10 になってますね。

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: localhost
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000009
Read_Master_Log_Pos: 811526263
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 240143
Relay_Master_Log_File: mysql-bin.000009
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 811523403
Relay_Log_Space: 243176
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 4
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1001
Master_UUID: b2e1a379-a554-11e6-88f4-9ca3ba01ee48
Master_Info_File: /var/lib/mysql2/master.info
SQL_Delay: 10
SQL_Remaining_Delay: 1
Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
1 row in set (0.00 sec)

これでMaster更新の10秒後にSlaveへデータが反映される動きになります。

具体的な例ではこんな感じです。

(1) 0:00 MasterでテーブルAを作成

(2) 0:05 MasterでテーブルBを作成

(3) 0:10 SlaveでテーブルAが作成される

(4) 0:15 SlaveでテーブルBが作成される

slave2の方でも同じように設定しておきましょう。


MySQL5.6よりも前のバージョンの場合

次に、MySQL5.6よりも前のバージョンの場合ですが、MySQLの機能ではサポートされていません。

そのため疑似的に遅延しているような感じにするPercona Toolkitに含まれているpt-slave-delayというPerlスクリプトを使います。

Percona Toolkit

https://www.percona.com/downloads/percona-toolkit/LATEST/

$ cd /usr/local/src/

$ mkdir PerconaToolkit
$ cd PerconaToolkit
$ wget https://www.percona.com/downloads/percona-toolkit/2.2.19/RPM/percona-toolkit-2.2.19-1.noarch.rpm
$ su -
# yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL ←pt-slave-delayにはこれが必要
# rpm -ivh percona-toolkit-2.2.19-1.noarch.rpm

私の設定の場合はMySQLのrootでレプリケーション設定を行っていますので、STOP SLAVEやSTART SLAVEをするにはルートでアクセスする必要があります。

そのため次のようなコマンドになるはず。(↓叩いた事無いので本当に動くのか見てませんが)

$ pt-slave-delay --delay 10s --interval 1s --run-time 10m -u root -P 3307 -p 127.0.0.1

pt-slave-delayのマニュアル

https://www.percona.com/doc/percona-toolkit/2.1/pt-slave-delay.html#

ただ、このスクリプトは次のような動きになり、MySQL5.6で設定した挙動とは異なります。

(1) 0:00 STOP SLAVE

(2) 0:04 MasterでテーブルAを作成

(3) 0:08 MasterでテーブルBを作成

(4) 0:10 START SLAVE

(5) 0:10 SlaveでテーブルAが作成される

(6) 0:10 SlaveでテーブルBが作成される

という感じになりますのでなかなか使い辛いですね・・・。

これを頑張って使うよりも、素直にMySQL5.6の機能を使った方が簡単だと思います。