单库分库分表后的数据迁移问题解决方案


随着公司业务的不断地扩展,数据会越来越多,当超过单数据库瓶颈的时候,就要考虑分库分表,但是这个时候就会涉及单表的数据如何按照分库分表规则分配到目前库表,并且保证数据的准确性。

1. 数据迁移

1.1 停机迁移

这种方式是最简单粗暴的,没有后续数据修正检验,一次性成功,但是存在一定的风险就是,如果在停机时间没有完成,就会需要再重新择时停机重新弄。另外就是要看公司的业务支不支持停机。主要的执行过程如下。

  1. 准备好迁移后兼容分库分表的系统发布包,用来数据迁移结束后上线使用;
  2. 提前准备好迁移的工具,也就是程序猿写好数据迁移的代码,另外要准备好迁移后的目标库表;
  3. 先选定用户活跃最少得时间段,这个时间段可以通过日常数据进行分析;
  4. 启动数据迁移,检查数据量是否正确,新系统发布上线,切换迁移后的目标库表。

1、2、3 准备工作很重要,要确保迁移损失的最小化。

1.2 双写迁移方案

在 Service 层实现数据的双写,在启动迁移方案前,将新入的数据在迁移目标库和旧数据库中都写一份,随之加上迁移动作,将旧数据迁移到新数据库中。

在不停机条件下需要对数据的迁移,这里推荐我们常用的一种方案,也就是在线双写的机制。

  1. 通过在写原有的数据库的同时也写一份数据到我们的新的库表中。
  2. 同样写一个后台迁移数据的程序,将我们的旧库的数据通过我们的数据库中间件迁移到新的多库表中。
  3. 在迁移的过程中,每次插入数据的时候,还需要检测数据的更新情况。比如,如果新的表中没有当前的数据,则直接新增;如果新表有数据并没有我们要迁移的数据新的话,我们就更新为当前数据,只能允许新的数据覆盖旧的数据。
  4. 经过一轮之后,也就是假如旧表中 1000 万条旧数据迁移完之后,我们就需要进行校验,校验两边数据是否是一模一样的。
  5. 这样反复的跑了几天之后,就数据库和新的数据库肯定是会一模一样的,最后观察下数据正常了,就可以停掉旧库的写入动作了。

2. 数据一致性验证

在迁移数据库的时候做一些必要的验证还是很有用的,比如说迁移前后的数据条数是否一致,数据是否一致,这个时候怎么办呢,验证条数还好说,要是验证数据是否一致呢,对于重要的数据当然要每条都不会有差错,随机抽样验证肯定是不行的,万一遗漏了就麻烦了,而且两张表不再同一台服务器上。

2.1 验证方案一

  1. 从表中选取几个重要字段,比如说 A、B、C,用这几个字段作为比对的标尺;
  2. 从原表中导出每条数据的这三个字段到一个文件 f1 中;
  3. 从目的表中到处每条数据的这三个字段到文件 f2 中;
  4. 比对文件 f1、f2 文件中的每条数据是否相同;
  5. 得出结论。

缺点:首先就是不是所有字段,仍然有可能在非主要字段出现 different;整体效率比较低。

2.2 验证方案二

  1. 对表中的每 n 条数据进行拼接(直接连接起来,n 取值取决于每条数据的数据量大小)。
  2. 计算这 n 条数据的 md5 值,添加到文件 f1 中,直到所有数据取值完成。
  3. 对目的表也一样,记录的文件 f2 中。
  4. 比对文件 f1、f2 文件的 md5 值,如果一致,ok,成功。
  5. 如果不一致,从上倒下比对每条 md5 值,找到第 m 条不一致。
  6. 得出结论,不一致的数据在 m*(n-1)+1 ~ m*n 之间,可以再次选择定位。

第二种方法的好处就是输出文件会在一定范围缩小,比对方便,但是也有缺点,不能像第一种方法一样直接通过关键字段定位不同数据的位置。


文章作者: 程序猿洞晓
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 程序猿洞晓 !
评论
 上一篇
Dockerfile的核心指令和编写案例 Dockerfile的核心指令和编写案例
Dockerfile是非常非常非常重要的文件,在镜像构建打包的时候,都是通过Dockerfile中的配置信息和相关执行来完成。
2023-07-08
下一篇 
Docker基础概念理解 Docker基础概念理解
K8S的使用率越来越高,K8S又依赖于Docker,因此Docker变成了必须会内容。之前都是专业的运维来做,现在更多的小公司形成不了完整的队伍,只能将Docker、K8S这些卷到了Java后端研发身上。
2023-07-01
  目录