前回の第24回 GTIDを使用したレプリケーション構成を作成する
特定のトランザクションをスキップする
従来のレプリケーションでは、Duplicate entry
などのエラーにてレプリケーションが停止してしまった場合に、SET GLOBAL sql_
を使用してトランザクションまたはSQLステートメントをスキップすることで、
GTIDを使用したレプリケーションでの対処方法として、
- 空のトランザクションを使用した方法
- gtid_
purgedを使用した方法
※ トランザクションをスキップすることはレプリケーションを継続できるだけでマスター・
意図的にレプリケーションがエラーで停止するようにして、
mysql> show slave status \G : : Slave_IO_Running: Yes Slave_SQL_Running: No Last_Errno: 1062 Last_Error: Error 'Duplicate entry '111' for key 'id'' on query. Default database: 'oo'. Query: 'insert into t values (111,111,111)' : Retrieved_Gtid_Set: 321e231b-3ce3-11e6-9fe5-0242ac110001:1-12 Executed_Gtid_Set: 3216e1ef-3ce3-11e6-9fe5-0242ac110003:1, 321e231b-3ce3-11e6-9fe5-0242ac110001:1-11
Retrieved_
からトランザクションID:12番目まで、
Executed_
からトランザクションID:11番目までスレーブで実行されたのがわかるので、Last_
が発生したということです。
それぞれの対処方法で12番目のトランザクションをスキップさせてみます。
空のトランザクションを使用した方法
スレーブで実行します。
セッション変数GTID_
に対象のGTIDを格納して、GTID_
にAUTOMATIC
をセットすることでスレーブのバイナリログには12番目のトランザクションに空のトランザクションが記述され、
mysql> SET GTID_NEXT='321e231b-3ce3-11e6-9fe5-0242ac110001:12'; mysql> BEGIN; mysql> COMMIT; mysql> SET GTID_NEXT='AUTOMATIC';
しかし、
FLUSH LOGS
でバイナリログをローテートさせ、
mysql> FLUSH LOGS; mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 198 | | mysql-bin.000002 | 686 | | mysql-bin.000003 | 427 | | mysql-bin.000004 | 191 | +------------------+-----------+ mysql> PURGE BINARY LOGS TO 'mysql-bin.000004';
そして、
mysql> START SLAVE;
gtid_purgedを使用した方法
gtid_
はバイナリログから消去されたすべてのトランザクションのセットを格納するグローバル変数です。gtid_
に対して先ほどのスキップさせたいトランザクションを設定します。
mysql> SET global gtid_purged='321e231b-3ce3-11e6-9fe5-0242ac110001:12'; ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
実行するとエラーとなりました。gtid_
が空欄でなければ設定できないという表示です。gtid_
はSHOW SLAVE STATUSのExecuted_
と同様の値で、RESET MASTER
を実施します。そして、gtid_
を設定します。
mysql> reset master; Query OK, 0 rows affected (0.02 sec) mysql> show global variables like 'GTID%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | gtid_executed | | | gtid_mode | ON | | gtid_owned | | | gtid_purged | | +---------------+-------+ mysql> SET global gtid_purged='321e231b-3ce3-11e6-9fe5-0242ac110001:12'; Query OK, 0 rows affected (0.01 sec) mysql> show global variables like 'GTID%'; +---------------+-----------------------------------------+ | Variable_name | Value | +---------------+-----------------------------------------+ | gtid_executed | 321e231b-3ce3-11e6-9fe5-0242ac110001:12 | | gtid_mode | ON | | gtid_owned | | | gtid_purged | 321e231b-3ce3-11e6-9fe5-0242ac110001:12 | +---------------+-----------------------------------------+
RESET MASTER
することによりスレーブのバイナリログはリセットされ、
そして、
mysql> start slave;
MySQL5.7からオンラインでGTIDへ変更することが可能
MySQL 5.
今回はMySQL 5.
をyumリポジトリーを使用しインストールして確認しています。事前に従来の方式でレプリケーションを設定しておきます。GTIDが有効でないことを確認します。
mysql> select @@gtid_mode; +-------------+ | @@gtid_mode | +-------------+ | OFF | +-------------+ 1 row in set (0.00 sec)
[手順1]マスター・スレーブ共にENFORCE_GTID_CONSISTENCY
をWARN
に設定
ENFORCE_GTID_CONSISTENCY
をWARN
に設定mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
WARN
にすることで、
# vim /var/log/mysqld.log 2016-06-28T09:15:55.818490Z 12 [Warning] Statement violates GTID consistency: CREATE TABLE ... SELECT.
[手順2]マスター・スレーブ共にENFORCE_GTID_CONSISTENCY
をON
に設定
ENFORCE_GTID_CONSISTENCY
をON
に設定ON
にすることでGTIDを使用したレプリケーションの制限事項に該当するワークロードがエラーログに出力されずにSQLエラーとして実行に失敗するようになります。
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON; mysql> create table tt2 select * from tt; ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
[手順3]マスター・スレーブ共にGTID_MODE
をOFF_PERMISSIVE
に設定
GTID_MODE
をOFF_PERMISSIVE
に設定OFF_
にすることで大きな変化はないですがバイナリログがローテートされます。
mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
[手順4]マスター・スレーブ共にGTID_MODE
をON_PERMISSIVE
に設定
GTID_MODE
をON_PERMISSIVE
に設定mysql> SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
ON_
にするとバイナリログがローテートされ、mysqlbinlog
でバイナリログを解析すると、GTID_
がANONYMOUS
からGTIDが設定されるようになります。
ON_PERMISSIVE
前#160712 4:10:51 server id 1 end_log_pos 219 CRC32 0x78f904bb Anonymous_GTID last_committed=0 sequence_number=1 SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
ON_PERMISSIVE
後#160712 4:13:45 server id 1 end_log_pos 219 CRC32 0x41ba155b GTID last_committed=0 sequence_number=1 SET @@SESSION.GTID_NEXT= 'e2d0e2a6-3d09-11e6-8bd9-0242ac110004:1'/*!*/;
スレーブはSHOW SLAVE STATUSを確認すると、Retrieved_
とExecuted_
にGTIDが設定されます。
Retrieved_Gtid_Set: e2d0e2a6-3d09-11e6-8bd9-0242ac110004:1 Executed_Gtid_Set: e2d0e2a6-3d09-11e6-8bd9-0242ac110004:1
[手順5]マスター・スレーブ共にステータス変数Ongoing_anonymous_transaction_count
が0
まで待機
Ongoing_anonymous_transaction_count
が0
まで待機これは従来のレプリケーション方式で更新されるステートメントがなくなるまで待つということです。
mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | Ongoing_anonymous_transaction_count | 0 | +-------------------------------------+-------+
[手順6]マスター・スレーブ共にFLUSH LOGSを実行する
GTIDを使用したバイナリログのみを残すためにFLUSH LOGS
を実行し、
mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 833 | | mysql-bin.000002 | 972 | +------------------+-----------+ mysql> flush logs; mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 833 | | mysql-bin.000002 | 972 | | mysql-bin.000003 | 194 | +------------------+-----------+ mysql> purge binary logs to 'mysql-bin.000003'; mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000003 | 194 | +------------------+-----------+
[手順7]マスター・スレーブ共にGTID_MODE
をON
に設定
GTID_MODE
をON
に設定GTID_
をON
にします。
mysql> SET @@GLOBAL.GTID_MODE = ON;
[手順8]スレーブでレプリケーションの再接続を一度だけ実行
オンラインでGTIDへ変更と書きましたが一度だけスレーブを停止する必要があります。すでにGTIDを使用したレプリケーションとして稼動していますが、MASTER_
を1にしてレプリケーションを開始します。
mysql> STOP SLAVE; mysql> CHANGE MASTER TO MASTER_AUTO_POSITION = 1 ; mysql> START SLAVE ;
最後にmy.
以上でオンラインでのGTIDの有効化が完了となります。
まとめ
今回は、
MySQLのフェールオーバの自動化を提供するツールmysqlfailover
やmysqlfabric
などは、