Mysql跨库数据迁移方案
Mysql跨库数据迁移方案
随着微服务的持续落地和业务量的快速发展,原先单实例单数据库的Mysql势必要进行多实例、分库分表的方向进行发展,来增加系统性能和减少彼此影响的概率。所以如何追求低停顿的数据迁移方案也成了摆在桌面上的问题。
1 停机维护
不是办法的办法,但是风险基本上是最小的,并且实现起来也很容易。
对于某些使用程度不高的业务来讲,在访问低谷期进行停机数据迁移是综合成本最小的方案。
2 基于强可靠的Kafka实现跨库迁移
惯用流程,上来一张图
整体方案分为以下六个阶段
标记数据迁移开始
然后将该段时间内的binlog都同步到消息队列中(我用的是Kafka)用于数据回放。
开启表数据的全量同步
全量的方案有很多,比如可以使用mysql自带的mysqldump来迁移,也可以写程序连JDBC进行查询迁移。
但是这时候,迁移的是当前数据库的快照数据,新修改的数据不用理会。
增量数据回放
由于上一步迁移的是快照数据,所以要把这一段时间内的增量数据给补齐。
补齐的方式很简单,之前的增量binlog已经都记录到Kafka中了,所以只需要放开消费者的限制,开始消费Kafka中的binlog即可。
数据追齐、对比
到此,数据迁移可以就算是结束了,所以要验证一下MQ中是否有消息残留,两边数据库的数据是否一致。
由于增量数据在持续的写入,所以数据对比小于100%是比较常见的,我这里的做法是,多次轮询扫描前次不一致的结果,在多次扫描后,如果百分百一致,即可认为数据对比通过。
相关业务下线,切换数据库地址重发发布
为什么要下线而不能一台一台的换?因为如果源库和同步库都有业务应用在写数据,很有可能会造成数据彼此的覆盖和不一致的情况发生,所以为了绝对可靠,需要相关应用下线统一切换数据源,因此也会造成短时间的业务不可用。
如果感觉业务并发写入量比较小,并且可以承担个别数据出现问题的情况,那么可以选择不停机切换数据库。
单元测试、业务流程回归验证
最后阶段,进行回归测试,查看新库有无问题发生。
因为我之前做了一个基于Canal的Mysql多端数据同步框架,所以这个流程基本上是基于这个框架扩展的,唯一增加了一点就是如果目标数据表在迁移阶段,要把相关binlog发送到Kafka当中。
整个方案的核心就是这个Kafka队列的配置,因为binlog的消费场景不同于其他的MQ,要保证强顺序和高可靠,不能发生消费错乱,也不能丢失任何一条binlog数据,所以Kafka的配置我单独写了一篇文章,请前往参考Kafka
方案优点:掌控性比较高,因为核心流程基本上全是要开发参与的,比如说记录binlog、传输Kafka、消费binlog、全量同步等核心步骤都是自己做的,可以进行个性化的定制。
方案缺点:
1. 需要额外的开发 。
2. 由于我现在是单线程进行binlog数据回放(为了保障顺序性),可能会出现消息堆积或者数据同步延迟的现象发生,从而导致停机时间扩大(要等MQ消费完)。
3 Mysql原生的主从同步方案
俗话说得好,当你手里拿的是锤子,你看什么都是钉子。
我之前完成沉迷于我自己那套数据同步方案中了,完成没有想到Mysql人家自己就有数据同步方案,并且同步延迟问题还处理的比较好了。。。。
Mysql自带了主从同步方案,并且在5.7.22版本后,对于并发同步的问题已经解决的差不多了,同步延迟已经能控制到一个比较满意的地步了,所以我立即抛弃了方案2,开始研究Mysql中的MTS。
这里对于MTS组提交、并行复制等概念就不详细讲了,Mysql官网和一些博客讲的比我要好(我也是从哪儿看到的),就直接上干货,通过实例来说明怎么进行配置。
首先Mysql要开启binglog、GTID支持,其中Master Mysql的my.conf要有以下配置
1 | mysql服务标识符 |
从库Mysql的my.conf配置如下
1 | mysql服务标识符 |
然后重启Mysql生效即可。
当配置项工作做完以后,开始进入数据迁移流程,有以下阶段
标记数据迁移开始
也就是记录一下开始时的Master数据库binlog位点信息,比如说binFile:mysql-bin.00xxxx Position: xxx。
如果开启了GTID支持的话,也可以记录GTID。
可以使用Mysql客户端运行show master status命令获得以上参数。
开启表数据的全量同步
开启从库同步
这里就要使用上一阶段记录的GTID当做数据同步的起始位点了,在Mysql客户端运行以下命令可以开启数据同步
1
2
3
4
5
6
7
8
9
10
11
12# 设置幂等模式,防止出现主键冲突错误
set global slave_exec_mode=’IDEMPOTENT’;
set global gtid_purged = '你记录下的GTID';
# 主库地址和有同步权限的用户
change master to master_host='xx', master_user='xx', master_password='xx', MASTER_AUTO_POSITION = 1;
# 开始同步
start slave;
# 查看从库同步状态
show slave status \G;数据对比
停机切换数据源
回归测试
可以看到,如果用Mysql自身的方案,就不用再需要我们进行额外的开发工作了,输一输命令就完成了。并且主从同步已经问世好多年了,算是比较成熟的方案了,如果中途碰到了什么问题,基本上也都可以面向百度解决。