前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于MySQL GTID的一次深刻学习

关于MySQL GTID的一次深刻学习

作者头像
jeanron100
发布2019-12-24 13:32:44
6920
发布2019-12-24 13:32:44
举报
文章被收录于专栏:杨建荣的学习笔记

最近因为一个特别的操作需求,需要临时配置一下双主复制模式。

在这个过程中让我从开始的悲观,无助到理解后的喜悦,GTID的使用模式确实给了我很多的意外惊喜,也让我对这个特性的过程有了进一步的理解。

我在书中对于GTID的特性使用了如下的图来表达。

现在的场景是一个一主一从的数据库,已经配置了从库。

在上线前进行了模拟演练,做过主从切换,然后快速验证后又恢复了回来。现在想要实现的是一个双主的配置,即需要Slave->Master做一个反向的复制配置。

我在检查的时候,发现主从都存在两个GTID属主。

类似这样:

代码语言:javascript
复制
Executed_Gtid_Set: 
74a1e34b-8204-11e9-b7dd-005056b73821:1-20352047366,
99fbf089-9266-11e9-9a38-005056b70e42:1-5046391

其实这是因为在数据库运行过程中确实发生了两次切换导致,也通过这种方式能够清晰的记录下来GTID的变更历史,这本来没什么好说的,在配置反向关系的时候抛出了错误。

代码语言:javascript
复制
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

从错误信息来看,Master切换之后,Slave变成了主库,这个时候数据写入就在Slave端了,然后业务再次切换后数据开始在Master写入。这个过程中的切换会导致一部分的binlog写入是在Slave端生成,而这部分的binlog显然随着时间的变化会自动被服务清理掉。如果报出这样的错误,实在是比较尴尬和无奈的事情了,换句话说,我们要关注当前的状态和后续的改变,binlog我们不可能自始至终保留,而且就算保留拿来恢复也不显示,所以在这个过程中一定有什么特别的地方。

我把主从关于GTID的信息都整理出来,可以参考梳理后的结果。

在Master和Slave的UUID分别是以21和42结尾,仔细对比发现了端倪。

Master端:

Gtid_purged:

74a1e34b-8204-11e9-b7dd-005056b73821:1-20294065566,

99fbf089-9266-11e9-9a38-005056b70e42:1-5046391

Slave端

Executed_Gtid_Set:

74a1e34b-8204-11e9-b7dd-005056b73821:1-20354149730,

99fbf089-9266-11e9-9a38-005056b70e42:1-5046473

gtid_purged:

74a1e34b-8204-11e9-b7dd-005056b73821:1-20295253841,

99fbf089-9266-11e9-9a38-005056b70e42:1-5046473

42结尾的Slave端是做过一次故障切换的,切换后的状态应该是

1-5046391左右,而在Slave变为主库后写入了数据,状态应该是

1-5046473,总之在那之后基于这个GTID再无数据写入,具体在那个时间段里发生了什么已经无法知晓,但是一个值得考虑的点就是基于MHA的健康监测是使用了ping insert的方式,在没有业务数据干扰的情况下,很可能是这个潜在的原因写入了数据,但是至于为什么没有把这些变更都同步过去,这是一个问题。当然对我们解决这个问题不是最重要的。

我们可能需要理解一下这个问题的根本原因,其实不在于是不是存在两个GTID,而是根本在于Slave端的GTID(不变化的GTID)在两端不一致。

可以举个例子,比如夫妻两个人(类似于Master,Slave两个节点,为了便于理解,我就以媳妇(Master),丈夫(Slave)来简称了),先是媳妇管账,GTID以媳妇(Master)的变化为准,然后过了一段时间发生了转换,该丈夫管账,数据变化以Slave为主,结果管得不好,很快又换过来了,于是又以媳妇的(Master)为准。

隔了很久,夫妻两人要共同管账(配置双主模式),需要把之前的消费情况理一理。 结果发现丈夫(Slave)管账的时候有一部分的账目不一样,即媳妇(Master端)看到的账目和丈夫(Slave端)看到的不一样,媳妇这边是5046391笔交易,丈夫这边记录的是5046473笔交易,结果丈夫也记不得这个过程的消费记录,所以这种情况下就需要做一些修正和稽核。

这个情况有些类似,我们的思路是先修正两边的GTID(不变化的部分),然后再重新建立双向复制关系。

修复过程

修复过程其实比较清晰,那就是现在是以Master端的GTID为准,那么我们就不能在Master端做任何reset master的操作,所以记录的修正应该是以Master为准,所有的操作应该是在Slave端完成。

Slave端修复的步骤如下:

1)stop slave;

2)show slave status\G

记录下来得到的Executed_Gtid_Set值,这是截止stop slave时最新的GTID状态信息。

3)reset master;

切记是在Slave端执行,这个阶段的目的就是要重新配置GTID的校准值。这个时候mysql.gtid_executed应该就是空的了。

4)重置GTID_purged值

这个步骤是关键所在。我们需要配置为最新的SET的GTID值,这样就不用重复消费哪些事务数据了,而原来的GTID从5046473修改为5046391

SET @@GLOBAL.GTID_PURGED='74a1e34b-8204-11e9-b7dd-005056b73821:1-20363492180,99fbf089-9266-11e9-9a38-005056b70e42:1-5046391';

5)删除从库的复制配置

reset slave all;

6)配置复制关系

CHANGE MASTER TO MASTER_USER='dba_repl', MASTER_PASSWORD='xxxx' , MASTER_HOST='xxxxx',MASTER_PORT=4307,MASTER_AUTO_POSITION = 1;

7)重启Slave节点,查看状态

start slave;

show slave status\G

修复完成后,再次建立复制关系就是水到渠成的事情了,当然也可以随建随删。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档