一、背景

MySQL作为最流行的关系型数据库产品之一,当数据规模增大遭遇性能瓶颈时,最容易想到的解决方案就是分库分表。无论是进行水平拆分还是垂直拆分,第一步必然需要数据迁移与同步。由此可以衍生出一系列数据迁移过程中的需求:

1.原本一张表迁移到单库多表(或多库多表),这是最基本的需求;

2.原本单库多表(或多库多表)迁移到新的多库多表(因表设计不合理、数据规模增大等原因导致需要再次分库分表)

3.新表与旧表的表结构可能不一致,如:类型表更(自增主键id由int改为bigint)、字段数量不一致(删减、增加)、字段名称变更等

4.字段映射,如:旧表中的多个字段映射为新表的一个字段,或旧表中的一个字段映射为新表的多个字段

5.增量数据的实时同步,以及当涉及表结构转换时增量部分(binlog)如何方便地实现同样的转换

6.如何支持垂直拆分的数据迁移

7.MySQL到NewSQL的迁移(如:TiDB、CockroachDB)

8.异构数据源的实时迁移,如:MySQL到HBase、MongoDB(关于异构数据源的实时同步设计不在本文内容范围,后续将专题介绍)

9.迁移前后的数据一致性校验

二、设计

为满足以上需求,下面将从全量迁移和增量同步两部分来说明MySQL数据迁移同步工具的设计与实现。

2.1 全量迁移

mysqldump是MySQL官方自带的数据备份工具,也可以用于数据迁移,但不足之处是单线程处理,迁移大表时速度极慢,并且不支持写入分库分表。因此开源社区还开发了一个多线程的类似工具mydumper,性能有不少提升,但同样不支持写入分库分表,也不支持字段的转换。

接下来介绍下快速分片并行读取MySQL表数据的做法:

1、自动查找表的主键pk;

2、查询主键的最大值及最小值:max(pk),min(pk);

3、对主键范围分片,每个分片跨度1万(即最多读取1万行数据),由此即可将整张表的查询分成多个查询分片:

第1个分片查询条件为pk >= min(pk) AND pk < min(pk)+10000

第2个分片查询条件为pk>= min(pk)+10000 AND pk < min(pk)+20000

第3个分片查询条件为pk >= min(pk)+20000 AND pk < min(pk)+30000

以此类推。

以上分片查询除了可以并行读取之外,另外一个优势是失败可恢复,某个分片查询失败并不影响整体查询的进度,只需失败重试即可。当然也可以将所有分片持久化,即使程序异常退出,重启后也可以恢复,避免重新查询全表数据。

2.2 增量同步

增量数据的读取基于MySQL的binlog主从复制。在全量迁移之前首先获取当前MySQL的位点信息(FileName、Position),以便全量数据迁移完成之后从该位点继续重放binlog。

三、实现

3.1 全量迁移

基于RxJava的观察者(或生产者消费者)模式实现链式最大化并行处理:多张表并行生成查询分片(Query Split),然后由Source并行执行查询分片从MySQL中读取数据,然后统一由Sink Selector根据分库分表的sharding字段及规则计算出每行数据所属的slot(即应该写入到哪张分表),当一个slot中的数据积累到一个batch size时会生成一个插入分片(Insert Split),最终由Sink并行地批量写入对应的目标表中。

为了避免累积的数据过多造成GC压力,slot超过一定时间后即使没有累积到一个batch size也会生成Insert Split分发给Sink执行写入。此外还要考虑另外一个问题:当生产者生产过快导致消费者来不及处理时,将会导致事件堆积,严重时还会OOM,即所谓的背压(Backpressure)。幸好RxJava作为一个成熟的Reactive框架已经对背压处理有很好的支持,这也是为什么要基于RxJava来实现的重要原因之一。

3.2 增量同步

binlog的抽取使用了开源的Java类库mysql-binlog-connector-java,与Canal相比更加轻量,源码清晰易懂,不依赖其他第三方jar包,也没有那么多不需要的繁杂功能。

为了实现对binlog的字段转换,采用了Apache开源的SQL引擎calcite来实现:将binlog的每行数据根据原表的表结构映射为一张内存表,然后由calcite执行SQL转换后输出结果。(PS:calcite当前已被多个开源项目采用,Hive用calcite优化查询,Flink的Streaming SQL基于calcite实现,Kylin的查询引擎也采用calcite)

3.3 数据校验

因MySQL表的checksum与数据的行顺序无关,当新表与旧表的表结构相同并且数据不需要转换时采用执行CHECKSUM TABLE tbl_name查询语句获取每张新表和旧表的checksum,然后分别求和对比最终的checksum是否相同以此校验数据是否一致。

当新表与旧表存在字段类型变更、字段数量不一致、数据经过转换等会导致checksum发生变化时,采用排除有关字段,由迁移工具内部只对剩余字段数据进行checksum计算。Checksum算法可以选择CRC32或Adler32,这两种算法均采用Java自带的实现类,默认情况下使用Adler32因为其具有更快的计算效率。

四、总结

无论是分库分表常规方案的实施,还是未来新一代分布式关系型数据存储NewSQL的落地实践,数据的迁移与同步都是必不可少的重要环节。毕竟,快速、准确、平滑地完成数据迁移,便已成功了一半。

mysql数据迁移工具_MySQL数据迁移工具的设计与实现相关推荐

  1. mysql导出数据 程序_MySQL数据导出与导入程序代码

    Mysql Manual讲得很清楚.实现数据备份有两种方法,一是直接copy mysql data目录的数据文件.第二种就是mysqldmup. 第一方法,没什么可言,也就是写写脚本或是放置ftp上面 ...

  2. mysql decode语句_mysql数据灾难恢复方案

    数据库备份:将数据库中存在的现有数据,进行存放成为副本数据,可以解决数据容灾,提高系统的高可用性和灾难恢复性,数据崩溃时,以最小代价重新恢复数据.数据备份的分类: 物理备份:指对数据库操作系统的物理文 ...

  3. mysql中数据定义和数据控制语言_MySQL 数据定义语言(DDL)

    SQL 包含以下 4部分:1数据定义语言(DDL):DROP.CREATE.ALTER 等语句.2数据操作语言(DML):INSERT(插入).UPDATE(修改).DELETE(删除)语句.3数据查 ...

  4. mysql数据库迁徙_mysql数据迁徙详解

    数据迁徙是每个后端都会遇到的工作之一,本文介绍了一些常见的数据迁徙方法与工具 mysqldump:数据结构不变的数据迁徙 导出数据 mysqldump -u root -p DATABASE_NAME ...

  5. mysql数据库迁徙_Mysql数据迁徙方法工具解析

    这篇文章主要介绍了mysql数据迁徙方法工具解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 数据迁徙是每个后端都会遇到的工作之一,本文介绍了一些 ...

  6. mysql数据迁移_Mysql数据迁移方法

    MySQL迁移通常使用的有三种方法: 1.数据库直接导出,拷贝文件到新服务器,在新服务器上导入. 2.使用第三方迁移工具. 3.数据文件和库表结构文件直接拷贝到新服务器,挂载到同样配置的MySQL服务 ...

  7. mysql集群数据引擎_MySQL数据引擎

    InnoDB存储引擎 该引擎是MySQL数据库的默认事务型引擎,它被设计用来处理大量短期事务(绝大多数正常提交,很少回滚) InnoDB的数据存储在表空间中,表空间是由InnoDB管理的一个黑盒子,由 ...

  8. mysql 200列_Mysql数据表基本

    bit[(M)] 二进制位(101001),m表示二进制位的长度(1-64),默认m=1tinyint[(m)] [unsigned] [zerofill] 小整数,数据类型用于保存一些范围的整数数值 ...

  9. mysql 的数据备份_MySQL 数据备份与还原

    一.数据备份 1.使用mysqldump命令备份 mysqldump命令将数据库中的数据备份成一个文本文件.表的结构和表中的数据将存储在生成的文本文件中. mysqldump命令的工作原理很简单.它先 ...

最新文章

  1. 自然哲学的数学原理_慢跑的数学原理(一):珍惜做的每一份功
  2. [剑指offer]面试题第[65]题[JAVA][不用加减乘除做加法][位运算]
  3. java激光推送ios_关于ios极光推送server端注意的地方
  4. 自学提高:JVM点滴
  5. C语言丨函数的递归调用和递归函数
  6. 《苹果》何以成禁果?
  7. form表单无刷新提交文件(iframe)
  8. 动态生成li 根据后台返回个数动态生成li
  9. Unity游戏画面品质增强,shader和贴图
  10. 再也不见,Itchat!
  11. 图解 FAT 文件系统基础知识
  12. 【解决】Failed to process import candidates for configuration class [cn.itcast.eureka.EurekaApplication]
  13. android 电池权限,Android M及以上提示用户将APP加入电池优化白名单
  14. webotAI网页版上线啦!
  15. NEON Intrinsics 练习题
  16. 1036:镂空三角形
  17. 使用sqlhelper类查询时假如不需要参数化,那到时SqlParameter这个传参怎么处理
  18. MySQL - 设计游戏用户信息表
  19. html flag属性,html5 的flag是什么意思?
  20. 23.Odoo产品分析 (三) – 人力资源板块(4) – 招聘流程(1)

热门文章

  1. openmpi参数_MPI初学-安装及OpenMPI函数说明
  2. 如何设置 Altaro Offsite Server 以进行复制
  3. 肺功能曲线图怎么看_肺功能报告单怎么看 专家详解肺功能报告单?
  4. mysql的最左匹配原则
  5. 香港服务器适合的网站,香港服务器优势是什么?
  6. 动手学深度学习V2.0(Pytorch)——23. LeNet(mnist)
  7. Gnocchi 7、Gnocchi中的水平扩展
  8. Linux内核Ramdisk(initrd)机制
  9. apply和call的应用
  10. 计算机网络专业单招考试科目,2020年四川职业技术学院单独招生考试计算机网络技术专业技能测试考试大纲...