MySQL道普請便り

第25回 GTIDを使用したレプリケーション構成を作成する[2]

この記事を読むのに必要な時間:およそ 4.5 分

MySQL5.7からオンラインでGTIDへ変更することが可能

MySQL 5.7.6以降から従来のレプリケーション構成から,オンラインにてGTIDを使用したレプリケーション構成へ変更が可能です。

今回はMySQL 5.7.13をyumリポジトリーを使用しインストールして確認しています。事前に従来の方式でレプリケーションを設定しておきます。GTIDが有効でないことを確認します。

mysql> select @@gtid_mode;
+-------------+
| @@gtid_mode |
+-------------+
| OFF         |
+-------------+
1 row in set (0.00 sec)

[手順1]マスター・スレーブ共にENFORCE_GTID_CONSISTENCYWARNに設定

mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;

WARNにすることで,前回説明したGTIDを使用したレプリケーションの制限事項に該当するワークロードが,エラーログに出力されるようになります。ここで出力されるワークロードが存在した場合は,アプリケーションのコードを直すなど,事前に対応しておきます。

# vim /var/log/mysqld.log
2016-06-28T09:15:55.818490Z 12 [Warning] Statement violates GTID consistency: CREATE TABLE ... SELECT.

[手順2]マスター・スレーブ共にENFORCE_GTID_CONSISTENCYONに設定

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_MODEOFF_PERMISSIVEに設定

OFF_PERMISSIVEにすることで大きな変化はないですがバイナリログがローテートされます。

mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;

[手順4]マスター・スレーブ共にGTID_MODEON_PERMISSIVEに設定

mysql> SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;

ON_PERMISSIVEにするとバイナリログがローテートされ,mysqlbinlogでバイナリログを解析すると,GTID_NEXTANONYMOUSから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_Gtid_SetExecuted_Gtid_SetにGTIDが設定されます。

Retrieved_Gtid_Set: e2d0e2a6-3d09-11e6-8bd9-0242ac110004:1
Executed_Gtid_Set: e2d0e2a6-3d09-11e6-8bd9-0242ac110004:1

[手順5]マスター・スレーブ共にステータス変数Ongoing_anonymous_transaction_count0まで待機

これは従来のレプリケーション方式で更新されるステートメントがなくなるまで待つということです。

mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
+-------------------------------------+-------+
| Variable_name                       | Value |
+-------------------------------------+-------+
| Ongoing_anonymous_transaction_count | 0     |
+-------------------------------------+-------+

[手順6]マスター・スレーブ共にFLUSH LOGSを実行する

GTIDを使用したバイナリログのみを残すためにFLUSH LOGSを実行し,それまでのバイナリログを削除します。GTIDが有効なバイナリログと,それ以外の状態のバイナリログが混ざるとPITRができないためです。よって,GTIDの有効化前にフルバックアップの取得とバイナリログのバックアップをしておくことは大切です。

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_MODEONに設定

GTID_MODEONにします。

mysql> SET @@GLOBAL.GTID_MODE = ON;

[手順8]スレーブでレプリケーションの再接続を一度だけ実行

オンラインでGTIDへ変更と書きましたが一度だけスレーブを停止する必要があります。すでにGTIDを使用したレプリケーションとして稼動していますが,GTIDをベースにレプリケーションを再開できるようにレプリケーションを停止して,MASTER_AUTO_POSITIONを1にしてレプリケーションを開始します。

mysql> STOP SLAVE;
mysql> CHANGE MASTER TO MASTER_AUTO_POSITION = 1 ;
mysql> START SLAVE ;

最後にmy.cnfにGTID設定の記述を追加します。

以上でオンラインでのGTIDの有効化が完了となります。

まとめ

今回は,GTIDを使用したレプリケーション時の特定のトランザクションをスキップする方法と,MySQL5.7から可能となったオンラインでGTIDへ変更方法について説明しました。

MySQLのフェールオーバの自動化を提供するツールmysqlfailovermysqlfabricなどは,GTIDを使用したレプリケーションが前提となっています。今後のMySQLの高可用性を保つためにはGTIDが必須であるといえます。

著者プロフィール

北川健太郎(きたがわけんたろう)

LINE株式会社所属のデータベースエンジニア。担当はMySQLとOracle Database。好きなMySQLの機能はレプリケーションで,好きなOracleDatabaseの機能はログオントリガー。

Twitter:@keny_lala

コメント

コメントの記入