MySQL道普請便り

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

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

前回の第24回 GTIDを使用したレプリケーション構成を作成する[1]に続いてGTIDについて紹介します。今回は,レプリケーションがエラーで停止してしまった際の対処方法と,MySQL5.7から可能となったオンラインでのGTIDの有効化について説明します。

特定のトランザクションをスキップする

従来のレプリケーションでは,Duplicate entryなどのエラーにてレプリケーションが停止してしまった場合に,SET GLOBAL sql_slave_skip_counter = Nを使用してトランザクションまたはSQLステートメントをスキップすることで,レプリケーションの継続ができました。しかし,GTIDを使用したレプリケーションではこの構文が使用できません。

GTIDを使用したレプリケーションでの対処方法として,以下の2点があります。

  1. 空のトランザクションを使用した方法
  2. 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_Gtid_Set: 321e231b-3ce3-11e6-9fe5-0242ac110001:1-12からトランザクションID:12番目まで,スレーブはマスターから更新情報を受け取っているのがわかります。

Executed_Gtid_Set: 3216e1ef-3ce3-11e6-9fe5-0242ac110003:1,321e231b-3ce3-11e6-9fe5-0242ac110001:1-11からトランザクションID:11番目までスレーブで実行されたのがわかるので,12番目のトランザクションにてLast_Error: Error 'Duplicate entryが発生したということです。

それぞれの対処方法で12番目のトランザクションをスキップさせてみます。

空のトランザクションを使用した方法

スレーブで実行します。

セッション変数GTID_NEXTに対象のGTIDを格納して,空のトランザクションを実行します。その後,GTID_NEXTAUTOMATICをセットすることでスレーブのバイナリログには12番目のトランザクションに空のトランザクションが記述され,レプリケーションを開始することで,次の13番目のトランザクションをマスターに要求するようになります。

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_purgedはバイナリログから消去されたすべてのトランザクションのセットを格納するグローバル変数です。gtid_purgedに対して先ほどのスキップさせたいトランザクションを設定します。

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_executedが空欄でなければ設定できないという表示です。gtid_executedはSHOW SLAVE STATUSのExecuted_Gtid_Setと同様の値で,これをを空欄にするにはスレーブでRESET MASTERを実施します。そして,gtid_purgedを設定します。

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することによりスレーブのバイナリログはリセットされ,指定したトランザクション番号以降(今回の例では13番目)のトランザクションから記述されます。

そして,レプリケーションを開始させます。

mysql> start slave;

著者プロフィール

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

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

Twitter:@keny_lala

コメント

コメントの記入