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
( ´-`).oO(なんかmysqld --verbose --helpと ドキュメント で設定できる値が違うぞ。。正解はOFF, OFF_PERMISSIVE, ON_PERMISSIVE, ONの4つでした。mysqldが正解。
まずはフツーにgtid_mode= OFFでレプリケーションを組む。
この時点から既に、マスターでもスレーブでもバイナリーログに@@gtid_next= 'ANNONYMOUS'が出力されている。
コイツが緩衝材の役割を果たしてくれるっぽい。スレーブ側でOFF_PERMISSIVEに変更。
この時点では目だった変化はない(CHANGE MASTER TO master_auto_position= 1もできない)し、スレーブにクエリーを発行しても
まだGTIDらしきものはバイナリーログに入っていない。
スレーブをON_PERMISSIVEに。
スレーブで実行したクエリーにはGTIDが振られるようになった。マスターから流れてきたクエリーに対しては
GTIDは振られない。うむうむ、いいんじゃないのこれ。
マスターも順番にOFF => OFF_PERMISSIVE => ON_PERMISSIVE => ONと続けてやると、
master_auto_position= 1にするためにはマスター側のgtid_modeがONであることと、スレーブ側のgtid_modeがOFF_PERMISSIVE以上であることが必要。
あと、OFF <=> OFF_PERMISSIVE <=> ON_PERMISSIVE <=> ON以外のパスでgtid_modeを設定しようとすると、
といって怒られる。
割と柔軟性があるつくりなので、きっちり順々に上げなくてもなんとかなった。
(スレーブOFF_PERMISSIVE => ON_PERMISSIVE, マスター OFF_PERMISSIVE => ON_PERMISSIVE => ON, スレーブ ONとかやっても動き続ける)
これ是非MySQL 5.6にもバックポートしてほしいですね。
(5.6.23現在、@@global.gtid_modeはread_only variableなのでSET GLOBALで変更できない)
PlanetMySQL Voting: Vote UP / Vote DOWN
今まで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で変更できない)
PlanetMySQL Voting: Vote UP / Vote DOWN