MYSQL Semi-Sync Replicationについて

Semi-Synchronous Replicationは、マスターでコミットされた処理がスレーブにも送信されて
スレーブにデータが送信されて受け取った事を確認してからAckをマスターに返して初めて、
処理が確定されます。なので以下の1の処理が完了しているので、マスターDBが破損してもデータの
損失を最小限に留める事が出来ます。
——————————————
 1. I/Oスレッド(スレーブバイナリーログ受信)
 2. SQLスレッド(スレーブにてバイナリーログを読み込んで実行)
——————————————
但し、Ackが発生するのはマスターとスレーブのログに書き込んでからなので
当然CPU、メモリー、ディスク、ネットワークが遅いとユーザーに返すレスポンスは極端に遅くなります。
特にFusion-IOやSSDを用いてディスクの遅延が無い環境ではネットワーク遅延が原因で、
DB処理が遅くなりユーザーへのレスポンスも極端に遅くなるので実装する時は十分な確認が必要です。

以前、オラクルを稼動させた外部ディスクにてのディスクのSync機能を利用して
遠隔地とDark Fiberを利用してディスクのMirrorをした時は、
オラクル処理の遅延を懸念して、データ、REDOログのディスクはA-SYNCにして非同期で同期して、
Archiveログで利用しているディスクだけSync設定にしてデータ保護していました。
障害発生時のシュミレーションではテーブルスペースに前日同期したテーブルスペースに、
同期してあるArchiveログを適用したら問題無く起動する事が出来ました。
RedoやControlファイルが壊れている場合は再作成で対応。

マスターDBにプラグインをインストール

mysql> select @@version;
+------------+
| @@version  |
+------------+
| 5.5.29-log |
+------------+
1 row in set (0.00 sec)

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.35 sec)

mysql> show variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | OFF   |
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
4 rows in set (0.00 sec)

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql>

スレーブにプラグインのインストール

mysql> select @@version;
+------------+
| @@version  |
+------------+
| 5.5.29-log |
+------------+
1 row in set (0.00 sec)

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.10 sec)

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

mysql>

install_plugin

設定を有効にしてみる。
オンラインで実行可能なので、SETコマンドで有効にした後に動作確認し、
次回再起動時に有効にする為にmy.cnfに設定を追加。

スレーブ側で念の為、既存のレプリケーションを停止しておいた。
既存のレプリケーション設定があったので念の為。

mysql> stop slave;
Query OK, 0 rows affected (0.08 sec)

mysql>

マスター側でsemi_syncの設定、タイムアウト値を変更して有効にする。
合わせてmy.cnf側も変更しておく。(次の再起動に備えて)

mysql> show variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | OFF   |
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
4 rows in set (0.00 sec)

mysql> set GLOBAL rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)

mysql> set GLOBAL rpl_semi_sync_master_timeout=5;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |
| rpl_semi_sync_master_timeout       | 5     |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
4 rows in set (0.00 sec)

mysql>

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000029 |      107 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

mysql>

マスター側で次回回帰同時の為に、semi_syncの設定を入れておく。

[root@HOME001 ~]# vi /etc/my.cnf
[root@HOME001 ~]# cat /etc/my.cnf | grep rpl_semi
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=5
[root@HOME001 ~]#

スレーブ側でSETコマンドで設定を有効にしてmy.cnfにも追加しておく。

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

mysql>  show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> set GLOBAL rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.01 sec)

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

mysql>

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: HOME001
                  Master_User: slave_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000029
          Read_Master_Log_Pos: 107
               Relay_Log_File: relay-bin.000035
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000029
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB: mysql,performance_schema
           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: 107
              Relay_Log_Space: 549
              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: NULL
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: 1
1 row in set (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql>

次回再起動時の為にスレーブのmy.cnfを変更

[root@HOME002 ~]# vi /etc/my.cnf
[root@HOME002 ~]# cat /etc/my.cnf | grep rpl
rpl_semi_sync_slave_enabled=1
[root@HOME002 ~]#

基本動作確認(データ同期)
同期は問題無いが、シンプルなInsertに若干時間がかかっているような気がする。
マスター、スレーブのI/OスレッドAck待ちの影響?
semi-sync

レプリケーションポジション確認
master

マスター書き込みとRelayログの更新時間確認
マスターDBにinsertと同時にスレーブ側のログ時間も更新されている事を確認。
log_time

レプリケーション障害発生時の留意点:
もしレプリケーションを構築していて、スレーブが破損してしまい
マスターからデータを持ってきてレプリケーションを再構築する場合には以下留意。
①マスターからDBコピー
②スレーブのmy.cnfにて(rpl_semi_sync_slave_enabled)をコメントアウト。
③①で展開したデータフォルダーを利用してMYSQLの再開
④以下のコマンドでスレーブ用に設定を変更する。

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.12 sec)
mysql> uninstall PLUGIN rpl_semi_sync_master;
Query OK, 0 rows affected (0.02 sec)

⑤CHANGE MASTER TOコマンドでスレーブを設定。
⑥②でコメントアウトした箇所のコメントを外す。
⑦MYSQLを再起動してshow slave status \Gで確認。

その他参考:遅延レプリケーション(MASTER_DELAY)
5.6からはMASTER_DELAYでレプリケーションを意図的に遅延させる事が出来るそうなので、
オペミスしたら直ぐに最新のデータを戻す為の用途などに利用出来そうです。

遅延が無い場合は、以下の遅延状況は0秒になっていて良いのですがもしオペミスでデータ破損してしまった場合は、
即時ミスも反映されてしまうので、バックアップ専用スレーブDBなどには遅延を入れて運用すると良いかもしれません。

通常

[root@HOME002 ~]# mysql -u root -ppassword -e "show slave status\G" | grep "Seconds_Behind_Master"
        Seconds_Behind_Master: 0
[root@HOME002 ~]#

設定方法

CHANGE MASTER TO MASTER_DELAY = N;

運用ケース

To protect against user mistakes on the master. A DBA can roll back a delayed slave to the time just before the disaster.

To test how the system behaves when there is a lag. For example, in an application, a lag might be caused by a heavy load on the slave. However, it can be difficult to generate this load level. Delayed replication can simulate the lag without having to simulate the load. It can also be used to debug conditions related to a lagging slave.

To inspect what the database looked like long ago, without having to reload a backup. For example, if the delay is one week and the DBA needs to see what the database looked like before the last few days’ worth of development, the delayed slave can be inspected.

16.3.9. Delayed Replication
MySQL 5.6.0-m4登場

参考

Semi-Synchronous Replication用プラグインをインストールする。
最強のMySQL HA化手法 – Semi-Synchronous Replication
MySQL5.5 Semisynchronous Replicationを試してみる ~構築編
MySQL 5.5 GA版が出たのでSemisynchronous Replicationを使ってみた
MySQL 準同期レプリケーション(Semisynchronous Replication)設定メモ
MySQLにおけるレプリケーション遅延の傾向と対策
http://www.day32.com/MySQL/
UNINSTALL PLUGIN 構文

Comments are closed.

Post Navigation