GA

2015/03/10

MySQL 5.7.6でGTIDのローリング有効化ができるようになったので、システム全体を一度にシャットダウンしなくてもOK

MySQL 5.7.6メモそのいくつか。
今までgtid-mode= ONとOFFのマスター, スレーブは混在できなかったので、ONにするときは一度レプリケーション群を全部止めて起動しなおさなければいけなかった。それが、出来るようになったという話。

MySQL Bugs: #71543: A new GTID_MODE is needed to evaluate/migrate to GTID: ANONYMOUS_IN-GTID_OUT.
MySQL :: WL#7083: GTIDS: set gtid_mode=ON online


Percona Server 5.6.22では一足先にリリースされてましたね。やってることは同じだけど実装が違うっぽい予感。
Online GTID rollout now available in Percona Server 5.6



[root@f51faa7d23c3 ~]# mysqld --verbose --help | less
..
  --gtid-mode=name    Controls whether Global Transaction Identifiers (GTIDs)
                      are enabled. Can be OFF, OFF_PERMISSIVE, ON_PERMISSIVE,
                      or ON. OFF means that no transaction has a GTID.
                      OFF_PERMISSIVE means that new transactions (committed in
                      a client session using GTID_NEXT='AUTOMATIC') are not
                      assigned any GTID, and replicated transactions are
                      allowed to have or not have a GTID. ON_PERMISSIVE means
                      that new transactions are assigned a GTID, and replicated
                      transactions are allowed to have or not have a GTID. ON
                      means that all transactions have a GTID. ON is required
                      on a master before any slave can use
                      MASTER_AUTO_POSITION=1. To safely switch from OFF to ON,
                      first set all servers to OFF_PERMISSIVE, then set all
                      servers to ON_PERMISSIVE, then wait for all transactions
                      without a GTID to be replicated and executed on all
                      servers, and finally set all servers to GTID_MODE = ON.
..


( ´-`).oO(なんかmysqld --verbose --helpと ドキュメント で設定できる値が違うぞ。。正解はOFF, OFF_PERMISSIVE, ON_PERMISSIVE, ONの4つでした。mysqldが正解。


まずはフツーにgtid_mode= OFFでレプリケーションを組む。
この時点から既に、マスターでもスレーブでもバイナリーログに@@gtid_next= 'ANNONYMOUS'が出力されている。


[root@2d38323d5eb5 ~]# mysqlbinlog /usr/local/mysql/data/bin.000003
..
# at 360
#150217 19:17:16 server id 161  end_log_pos 425 CRC32 0xc1a16911        Anonymous_GTID  last_committed=1        sequence_numbe
r=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 425
#150217 19:17:16 server id 161  end_log_pos 513 CRC32 0x3893ffcc        Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1424168236/*!*/;
create database d1
/*!*/;
..

[root@f51faa7d23c3 ~]# mysqlbinlog /usr/local/mysql/data/bin.000002
..
# at 360
#150217 19:17:16 server id 161  end_log_pos 425 CRC32 0x0f90114c        Anonymous_GTID  last_committed=1        sequence_numbe
r=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 425
#150217 19:17:16 server id 161  end_log_pos 513 CRC32 0x3893ffcc        Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1424168236/*!*/;
create database d1
/*!*/;
..

コイツが緩衝材の役割を果たしてくれるっぽい。スレーブ側でOFF_PERMISSIVEに変更。


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

mysql> SET GLOBAL gtid_mode= 'OFF_PERMISSIVE';
Query OK, 0 rows affected (0.05 sec)

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

この時点では目だった変化はない(CHANGE MASTER TO master_auto_position= 1もできない)し、スレーブにクエリーを発行しても


[root@f51faa7d23c3 ~]# mysqlbinlog /usr/local/mysql/data/bin.000003
..
# at 426
#150217 19:24:49 server id 162  end_log_pos 491 CRC32 0xedeaa731        Anonymous_GTID  last_committed=1        sequence_number=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 491
#150217 19:24:49 server id 162  end_log_pos 603 CRC32 0xe284a3f5        Query   thread_id=6     exec_time=0     error_code=0
SET TIMESTAMP=1424168689/*!*/;
create database slave_only
..
/*!*/;

まだGTIDらしきものはバイナリーログに入っていない。


スレーブをON_PERMISSIVEに。


mysql> SET GLOBAL gtid_mode= 'ON_PERMISSIVE';
Query OK, 0 rows affected (0.03 sec)

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

mysql> DROP DATABASE slave_only;
Query OK, 0 rows affected (0.02 sec)

[root@f51faa7d23c3 ~]# mysqlbinlog /usr/local/mysql/data/bin.000004
..
# at 153
#150217 19:26:46 server id 162  end_log_pos 218 CRC32 0x9a581cd8        GTID    last_committed=0        sequence_number=1
SET @@SESSION.GTID_NEXT= '1e2c9249-b68b-11e4-ae86-0242ac1100a2:1'/*!*/;
# at 218
#150217 19:26:46 server id 162  end_log_pos 315 CRC32 0xb8794fef        Query   thread_id=11    exec_time=0     error_code=0
SET TIMESTAMP=1424168806/*!*/;
drop database slave_only
/*!*/;

スレーブで実行したクエリーにはGTIDが振られるようになった。マスターから流れてきたクエリーに対しては


mysql> INSERT INTO t1 VALUES (3, 'three');
Query OK, 1 row affected (0.01 sec)

[root@f51faa7d23c3 ~]# mysqlbinlog /usr/local/mysql/data/bin.000004
..
# at 1239
#150217 19:28:16 server id 161  end_log_pos 1304 CRC32 0x1fb41374       Anonymous_GTID  last_committed=5        sequence_number=6
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1304
#150217 19:28:16 server id 161  end_log_pos 1379 CRC32 0x7dd37323       Query   thread_id=8     exec_time=0     error_code=0
SET TIMESTAMP=1424168896/*!*/;
BEGIN
/*!*/;
# at 1379
#150217 19:28:16 server id 161  end_log_pos 1483 CRC32 0x2e8e2a4a       Query   thread_id=8     exec_time=0     error_code=0
SET TIMESTAMP=1424168896/*!*/;
INSERT INTO t1 VALUES (3, 'three')
/*!*/;
..

[root@f51faa7d23c3 ~]# mysqlbinlog /usr/local/mysql/data/bin.000004
..
# at 315
#150217 19:28:16 server id 161  end_log_pos 380 CRC32 0xbed7303c        Anonymous_GTID  last_committed=1        sequence_number=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 380
#150217 19:28:16 server id 161  end_log_pos 455 CRC32 0x0dedb2e0        Query   thread_id=8     exec_time=0     error_code=0
SET TIMESTAMP=1424168896/*!*/;
BEGIN
/*!*/;
# at 455
#150217 19:28:16 server id 161  end_log_pos 559 CRC32 0x64c2139f        Query   thread_id=8     exec_time=0     error_code=0
use `d1`/*!*/;
SET TIMESTAMP=1424168896/*!*/;
INSERT INTO t1 VALUES (3, 'three')
/*!*/;
..

GTIDは振られない。うむうむ、いいんじゃないのこれ。
マスターも順番にOFF => OFF_PERMISSIVE => ON_PERMISSIVE => ONと続けてやると、


mysql> SET GLOBAL gtid_mode= OFF_PERMISSIVE;

# at 153
#150217 19:31:08 server id 161  end_log_pos 218 CRC32 0x0aec73f2        Anonymous_GTID  last_committed=0        sequence_numbe
r=1
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 218
#150217 19:31:08 server id 161  end_log_pos 342 CRC32 0xb46d3cb9        Query   thread_id=9     exec_time=0     error_code=0
SET TIMESTAMP=1424169068/*!*/;
create database off_permissive
/*!*/;

mysql> SET GLOBAL gtid_mode= ON_PERMISSIVE;

# at 153
#150217 19:31:15 server id 161  end_log_pos 218 CRC32 0x261d23fa        GTID    last_committed=0        sequence_number=1
SET @@SESSION.GTID_NEXT= '7fea486e-b687-11e4-ae6f-0242ac1100a1:1'/*!*/;
# at 218
#150217 19:31:15 server id 161  end_log_pos 339 CRC32 0x3ab38b3d        Query   thread_id=9     exec_time=0     error_code=0
SET TIMESTAMP=1424169075/*!*/;
create database on_permissive
/*!*/;

mysql> SET GLOBAL gtid_mode= ON;

# at 193
#150217 19:31:32 server id 161  end_log_pos 258 CRC32 0x175fe321        GTID    last_committed=0        sequence_number=1
SET @@SESSION.GTID_NEXT= '7fea486e-b687-11e4-ae6f-0242ac1100a1:2'/*!*/;
# at 258
#150217 19:31:32 server id 161  end_log_pos 394 CRC32 0xd9ff015c        Query   thread_id=9     exec_time=0     error_code=0
SET TIMESTAMP=1424169092/*!*/;
create database gtid_is_on_at_last
/*!*/;

master_auto_position= 1にするためにはマスター側のgtid_modeがONであることと、スレーブ側のgtid_modeがOFF_PERMISSIVE以上であることが必要。
あと、OFF <=> OFF_PERMISSIVE <=> ON_PERMISSIVE <=> ON以外のパスでgtid_modeを設定しようとすると、


ERROR 1788 (HY000): The value of @@GLOBAL.GTID_MODE can only be changed one step at a time: OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON. Also note that this value must be stepped up or down simultaneously on all servers. See the Manual for instructions.

といって怒られる。



割と柔軟性があるつくりなので、きっちり順々に上げなくてもなんとかなった。
(スレーブOFF_PERMISSIVE => ON_PERMISSIVE, マスター OFF_PERMISSIVE => ON_PERMISSIVE => ON, スレーブ ONとかやっても動き続ける)

これ是非MySQL 5.6にもバックポートしてほしいですね。
5.6.23現在、@@global.gtid_modeはread_only variableなのでSET GLOBALで変更できない)

0 件のコメント :

コメントを投稿