启用GTID联机事务
如何在已经在线并使用匿名事务的服务器上启用GTID事务,以及可选的自动定位功能。此过程不需要使服务器离线,适合在生产环境中 使用。但是,如果您可以在启用GTID事务时使服务器脱机,那么处理就会更容易。
在开始安之前,请确保服务器满足以下前提条件:
.拓扑中的所有服务器必须使用MySQL 5.7.6或更高版本。您不能在任何一台服务器上在线启用GTID事务,除非拓扑中的所有服务器都使用此版本 。
.所有服务器都将gtid_mode设置为默认值OFF
启用GTID事务:
1.在每个服务器上执行:
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
主库1:10.18.30.50
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; Query OK, 0 rows affected (0.01 sec)
主库2:10.18.30.43
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; Query OK, 0 rows affected (0.01 sec)
从库:10.18.30.39
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; Query OK, 0 rows affected (0.01 sec)
让服务器在正常工作负载下运行一段时间,并监视日志。如果此步骤导致日志中出现任何警告,请调整应用程序,使其只使用gtid兼容的特性, 而不生成任何警告。
这是重要的第一步。在进入下一步之前,必须确保错误日志中没有生成警告。
2.在每个服务器上执行:
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
主库1:10.18.30.50
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON; Query OK, 0 rows affected (0.00 sec)
主库2:10.18.30.43
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON; Query OK, 0 rows affected (0.00 sec)
从库:10.18.30.39
mysql> SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON; Query OK, 0 rows affected (0.00 sec)
3.在每个服务器上执行:
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
主库1:10.18.30.50
mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; Query OK, 0 rows affected (0.01 sec)
主库2:10.18.30.43
mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; Query OK, 0 rows affected (0.01 sec)
从库:10.18.30.39
mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; Query OK, 0 rows affected (0.01 sec)
哪个服务器首先执行此语句并不重要,但重要的是,所有服务器都要在任何服务器开始下一步之前完成此步骤。
4.在每个服务器上执行:
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
主库1:10.18.30.50
mysql> SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; Query OK, 0 rows affected (0.01 sec)
主库2:10.18.30.43
mysql> SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; Query OK, 0 rows affected (0.01 sec)
从库:10.18.30.39
mysql> SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; Query OK, 0 rows affected (0.01 sec)
哪个服务器先执行该语句并不重要。
5.在每个服务器上,等待状态变量ONGOING_ANONYMOUS_TRANSACTION_COUNT为零。可以使用以下命令进行检查:
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
主库1:10.18.30.50
mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | Ongoing_anonymous_transaction_count | 0 | +-------------------------------------+-------+ 1 row in set (0.01 sec)
主库2:10.18.30.43
mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | Ongoing_anonymous_transaction_count | 0 | +-------------------------------------+-------+ 1 row in set (0.01 sec)
从库:10.18.30.39
mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | Ongoing_anonymous_transaction_count | 0 | +-------------------------------------+-------+ 1 row in set (0.01 sec)
注意:在复制从机上,理论上有可能显示为零,然后再次显示为非零。这不是问题,它显示一次零就足够了。
6.等待步骤5之前生成的所有事务复制到所有服务器。您可以在不停止更新的情况下执行此操作:唯一重要的是所有匿名事务都会被复制。
1.在主服务器执行:
SHOW MASTER STATUS;
主库1:10.18.30.50
mysql> SHOW MASTER STATUS; +---------------+----------+--------------+------------------+-------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+----------+--------------+------------------+-------------------------------------------+ | binlog.000007 | 194 | | | bb8b95d1-6f47-11ef-9592-005056a390e6:1-10 | +---------------+----------+--------------+------------------+-------------------------------------------+ 1 row in set (0.00 sec)
主库2:10.18.30.43
mysql> SHOW MASTER STATUS; +---------------+----------+--------------+------------------+-------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+----------+--------------+------------------+-------------------------------------------+ | binlog.000006 | 194 | | | 684e1f7d-6f47-11ef-a6d5-005056a3a162:1-10 | +---------------+----------+--------------+------------------+-------------------------------------------+ 1 row in set (0.00 sec)
记下“文件和位置”列中的值
2.在每个从属服务器上,使用来自主服务器的文件和位置信息执行:
SELECT MASTER_POS_WAIT('source_log_file', source_log_pos [, timeout][, channel])
从库:10.18.30.39
mysql> SELECT MASTER_POS_WAIT('binlog.000007',194,0,'master-1'); +---------------------------------------------------+ | MASTER_POS_WAIT('binlog.000007',194,0,'master-1') | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT MASTER_POS_WAIT('binlog.000006',194,0,'master-2'); +---------------------------------------------------+ | MASTER_POS_WAIT('binlog.000006',194,0,'master-2') | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT MASTER_POS_WAIT('binlog.000006',195,0,'master-2'); +---------------------------------------------------+ | MASTER_POS_WAIT('binlog.000006',194,0,'master-2') | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (0.00 sec)
返回值为0 ,代表从库已经应用了主库1binlog.000007 194与 主库2binlog.000006 194位置的数据。
如果有一个主服务器和多层的从服务器,或者换句话说,有从服务器的从服务器,那么在每层都重复第2步,从主服务器开始,然后是所有的直 接从服务器,然后是所有从服务器的从服务器,以此类推。
如果使用循环复制拓扑,其中多个服务器可能有写客户端,则对每个主从连接执行步骤2,直到完成整个循环。重复整个过程,这样你就可以完 成整个循环两次。
例如,假设你有3个服务器A、B和C,它们在一个循环中复制A -> B -> C -> A。过程如下:
? Do step 1 on A and step 2 on B. ? Do step 1 on B and step 2 on C. ? Do step 1 on C and step 2 on A. ? Do step 1 on A and step 2 on B. ? Do step 1 on B and step 2 on C. ? Do step 1 on C and step 2 on A.
7.如果您将二进制日志用于除了复制之外的任何事情,例如时间点备份和恢复,请等待,直到您不需要具有没有gtid的事务的旧二进制日志。
例如,在步骤6完成后,可以在正在备份的服务器上执行FLUSH LOGS。然后,要么显式地进行备份,要么等待您可能设置的任何定期备份例程的 下一次迭代。理想情况下,等待服务器清除步骤6完成时存在的所有二进制日志。还要等待步骤6之前所做的备份过期。
这是第二点。理解包含匿名事务的二进制日志(没有gtid)在下一步中是无法使用的,这一点至关重要。在此步骤之后,您必须确保没有GTIDs的 事务在拓扑中不存在。
8.在每个服务器上
mysql> SET @@GLOBAL.GTID_MODE = ON; Query OK, 0 rows affected (10.06 sec)
9.在每个服务器的my.cnf文件中加上gtid-mode=ON
现在可以保证所有的事务都有一个GTID(除了第5步或更早阶段生成的事务,它们已经被处理过)。要开始使用GTID协议以便稍后执行自动故障转 移,请在每个从服务器上执行以下操作。如果使用多源复制,可选地对每个通道执行此操作,并包括for channel channel子句:
STOP SLAVE [FOR CHANNEL 'channel']; CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel']; START SLAVE [FOR CHANNEL 'channel']; mysql> stop slave for channel 'master-1'; Query OK, 0 rows affected (0.02 sec) mysql> stop slave for channel 'master-2'; Query OK, 0 rows affected (0.01 sec) mysql> CHANGE MASTER TO MASTER_AUTO_POSITION = 1 for channel 'master-1'; Query OK, 0 rows affected (0.00 sec) mysql> CHANGE MASTER TO MASTER_AUTO_POSITION = 1 for channel 'master-2'; Query OK, 0 rows affected (0.00 sec) mysql> start slave for channel 'master-1'; Query OK, 0 rows affected (0.01 sec) mysql> start slave for channel 'master-2'; Query OK, 0 rows affected (0.00 sec)