• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

MySQL 5.7:在线开启和关闭基于GTID的复制

MySQL 5.7 彭东稳 7年前 (2016-11-21) 22292次浏览 已收录 0个评论

一、前言

MySQL在5.6版本之前复制一直是基于二进制日志的复制,到了MySQL5.6时开始支持基于事务(GTIDs)的复制,并且开始支持多线程复制;但MySQL5.6版本的多线程只能基于多库。这就牵扯到了一个应用场景,就是从基于日志的复制在线变更到基于事务的复制,在MySQL5.6版本时这一动作只能重启主服务器才可以做到。但是到了MySQL 5.7版本时已经可以支持在线变更复制类型了,也就是在线从基于二进制日志的复制变更为基于事务的复制。当然MySQL5.7在复制方面的改进不止这一点,还做到了基于表的多线程复制,以及多源复制。这篇文章只针对在线把基于日志的复制变更为基于事务的复制,其他方面的改进,如多线程复制和多源复制可以看其他文章。

二、安装MySQL 5.7.16

详情可看:MySQL 5.7多方式安装

首先从MySQL官方网站下载YUM源,地址:http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/

这里我选择MySQL 5.7的源进行安装MySQL 5.7,手动添加一个YUM源。

检查一下mysql repo

安装启动配置MySQL

MySQL 5.7以及安装完成了,为了简便,我这里使用多实例的方式进行测试在线变更复制类型,开两个端口3306和3307。

首先创建一些标准目录。

下面开始进行初始化操作。

看一下初始化后的目录文件,如下:

三、启动多实例

1. 给每个实例提供配置文件

给3306(master)实例提供一份配置文,如下:

给3307(slave)实例提供一份配置文件,如下:

PS:配置文件很清楚,如果想使用GTID,开启对应的参数即可。

重新赋予一下权限

四、基于日志做主从复制配置

1)启动两个实例

PS:进入MySQL需要使用-S指定各自的mysql.sock文件。

2)Master(3306)创建具有复制权限的用户

3)Slave(3307)连接至主库(3306)

4)启动Slave

OK,现在基于日志的主从复制已经完成了。

五、在线开启基于GTID的复制

接下来,就是在线切换复制类型了。首先确定主从的gtid_mode都是off状态。

1)Master(3306)操作

为了更加模拟线上环境,我们写一个脚本,一直往主库插入数据,同时从库也一直再同步主库的数据。

然后创建一个脚本一直往test.tt表中插入数据。

现在就可以开始丢在后台执行。

接下来,在主库(3306)和把enforce_gtid_consistency变成warn。

ENFORCE_GTID_CONSISTENCY这个参数主要有如下设置,主要用于不让违反GTID设置的操作执行,如果执行会报错如:Statement violates GTID consistency: CREATE TABLE … SELECT.

  • OFF:所有操作允许。
  • ON:不允许违反gtid的操作,并且报错。
  • WARN:在MySQL 5.7.6添加,所有操作允许,但是违反GTID的操作会报出警告。

ENFORCE_GTID_CONSISTENCY=WARN是确定事务都支持gtid,不会在err log中出现警告如下:

然后看一下error log。

如果没有错误信息,才可以进行下一步开启enforce_gtid_consistency操作。

然后进行开启gtid_mode操作,gtid_mode这个参数有四个值,一定要按照如下顺序进行gtid_mode的开启操作(关闭是相反的)。

  • off:生成的是匿名事务,slave也只能应用匿名事务。
  • off_permissive:生成的是匿名事务,slave可以应用匿名事务和GTID事务。
  • on_permissive:生成的是GTID事务,slave可以应用匿名事务和GTID事务。(这一步操作完成后,主节点二进制日志就会变成gtid模式)
  • on:生成的是GTID事务,slave也只能应用GTID事务。

当主库设置完gtid_mode=off_permissive之后,这个时候也要在从库执行到这一步,为的是slave可以应用匿名事务和GTID事务。切记,主从设置是交叉的,如果从库没有设置到gtid_mode=off_permissive,而主库下一步操作gtid_mode = on_permissive后,从库的IO线程就会断掉。带来的后果就是如果主从有延迟,那么主从数据很有可能会不一致。并且这种情况下,也不能算是一个完整的在线切换复制类型,只能算是半在线。

正确的做法就是如下操作,在从库也先进行如下设置:

2)Slave(3307)操作

当从库也设置完gtid_mode=off_permissive之后,就可以在主库进行开启GTID了。

3)Master(3306)操作

开启之后,由于脚本在一直写数据,你可以立马看见二进制状态的变化。

查看确定已经没有匿名事务了,这个值ONGOING_ANONYMOUS_TRANSACTION_COUNT有一次为0即可。

确定此时的Retrieved_Gtid_Set/Executed_Gtid_Set正常增长(甚至你可以在slave上使用:SELECT MASTER_POS_WAIT(file, position);来强制等待slave端直到指定位置,这个位置就是你确定的使用GTID事务的位置)。

可以看到当主库设置完gtid_mode = on_permissive后,二进制状态变成了GTID模式。这个时候就可以在从库开启gtid_mode = on_permissive了。

4)Slave(3307)操作

接下来show slave status就可以看到从库已经切换为GTID复制了。

5)Master&Slave都操作

下面就可以在主库和从库上分别设置gtid_mod = on了。

查看gtid的开启。

至此,主从复制在线切换GTID已经完成了。最后别忘了把gtid相关信息写进配置文件中,不然重启MySQL后就又失效了。具体可以看:MySQL基于GTIDs的复制实现

change master

如果出现主从不一致的情况,那么可以使用pt工具进行修复即可,详情请看这篇文章:使用pt-table-checksum&pt-table-sync检查和修复主从数据一致性

六、在线关闭基于GTID的复制

1)Slave操作

然后记录slave status

重新执行CHANGE MASTER

重新开启Slave。

2)Master&slave操作

生成的是GTID事物,slave可以应用匿名和GTID事物。

3)Master&Slave操作

生成的是匿名事物,slave可以应用匿名和GTID事物。

4)Master&Slave操作

等到主库和备库此显示为空,并且Retrieved_Gtid_Set/Executed_Gtid_Set不再变动。(甚至你可以在slave上使用:SELECT MASTER_POS_WAIT(file, position);来强制等待slave端直到指定位置,这个位置就是你确定的没有使用GTID事务的位置)

完成这一步实际上GTID事物已经没有生成和应用了。

5)Master&Slave操作

最后别忘记修改配置文件my.cnf,使其永久生效。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (3)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!