MySQL 5.7 启用GTID联机事务

启用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)

发表评论

电子邮件地址不会被公开。