Mysql数据库扩容与数据迁移

参考:
MySQL 数据库平滑扩容方案剖析
分库分表后如何实现不停机扩容

一 双写迁移方案

可通过 canal 或 mq 做实现

第一阶段:在线双写,查询走老库

  1. 建立好新的库表结构,数据写入老库的同时,也让写入拆分的新库。
  2. 数据迁移:使用数据迁移程序,将旧库的历史数据迁移到新库。避免增量影响,先断开主从,再导入(耗时较长), 同步完成并做校验
  3. 使用定时任务:新旧库的数据对比,补齐差异
    在这里插入图片描述

第二阶段:在线双写,查询走新库

  1. 完成了历史数据的同步和校验
  2. 把对数据库的读操作切换到新库,通过 Nginx,切换访问流量至新的服务。
  3. 依然向旧库写数据,观察业务一段时间,查看是否正常
    在这里插入图片描述

第三阶段:旧库下线

  1. 旧库不再写入新数据
  2. 经过一段时间,确定旧库没有请求之后,就可以下线旧库。
    在这里插入图片描述

平滑2N扩容方案

问题:使用取模分片后,如需进行扩容,新增节点时会有大量的旧数据需要迁移,迁移过程中可能需停服,等全部数据迁移完成后才能哈希到正确的数据库。但这样会面临大量的数据压力,并且对服务造成极大的不稳定性。

关键点:每个数据库都配置了一个从库,读写分离架构,从库和主库数据基本保持一致。扩容时,把所有的从库变成主库,这样主库就从N个变成了2N个。取模分片算法从id%N 变成 id%2N,使得扩容后原有数据不需要迁移

~~在这里插入图片描述~~
上图左侧时扩容前,有两个主库A和B,分别对应从库A0和B0。扩容后如右侧,有四个主库。

第一步:从库升级为主库

将A0和B0变成主库,此时整个库有一半的冗余数据,后续随时可以清理。
比如 uid=3
扩容前 两个库, 3%2=1, 存入B库,B0是从库,也存在该条数据
扩容后 四个库, 3%4=3,存入B0,而B中也有该数据,那么B库有冗余,后续随时可以清理。

第二步:逻辑层把取模分片算法从id%N改为id%2N。

调整数据库配置,通过配置中心更新,不需要重启。

扩容后取模分片算法目标分片不迁移原因
uid%4=0A原库,不需要迁移
uid%4=1B原库,不需要迁移
uid%4=2A0扩容前在A库,A0存在该数据 ,不需要迁移
uid%4=3B0扩容前在B库,B0存在该数据,不需要迁移

第三步:为2N个主库分布配置一个从库

保证数据库的高可用,也为下一次2N扩容做准备。

注意事项: 由于旧的主库一直在进行DML操作,从库不可能完全和主库的数据保持一致。所有需要从库和主库完全同步结束时才能升级为主库。 解决方案:主库停写一段时间,如停服一小时,或主库开启只读一段时间。

参考落地实现:平滑 2N 扩容方案实践

三 停机方案

1. 发布停服公告
为了进行数据的重新拆分,在停止服务之前,我们需要提前通知用户,比如:我们的服务会在 yyyy-MM-dd 进行升级,给您带来的不便敬请谅解

2. 停止服务
关闭 Service,不再对数据库进行增删改查等操作

3. 增加新的数据库节点
购买或建立新的数据库,建好数据库和表

4. 旧数据迁移
将旧库中的全部数据按照新的哈希算法,将数据重新分配,更新到正确的数据库

5. 数据校验
开发一个程序对旧库和新库中的数据进行校验,比对,确保重分配是正确的

6. 更改数据库配置和哈希算法
Service配置中添加新库连接地址,账号密码等;修改 Service 层的算法,也就是将原来的 uid%3 变为 uid%4

7. 恢复服务
重启 Service 服务

总结 停止服务之后, 能够保证迁移工作的正常进行。 但是服务停止,伤害用户体验, 而且造成了时间压力, 必须在指定的时间内完成迁移,且不能出错,每一步都要有回滚预案

四 停写方案

1. 发布停写公告
为了进行数据的重新拆分,我们需要提前通知用户,比如:我们的服务会在 yyyy-MM-dd 进行升级,期间不可进行某些操作,给您带来的不便敬请谅解

2. 停写,中断写操作(或拦截返回统一提示)
每个数据库设置为只读状态,关闭写的功能。在 Service 层对所有的写请求进行拦截,统一返回提示信息,如:服务正在升级中,只对外提供读服务

3. 增加新的数据库节点
购买或建立新的数据库,建好数据库和表

4. 旧数据增量式迁移
将旧库中的全部数据按照新的哈希算法,将数据重新分配,更新到正确的数据库。注意迁移时不可删除旧库的冗余数据,因为正在提供读服务

5. 数据校验
开发一个程序对旧库和新库中的数据进行校验,比对,确保重分配是正确的

6. 更改数据库配置和哈希算法
Service配置中添加新库连接地址,账号密码等;修改 Service 层的算法,也就是将原来的 uid%3 变为 uid%4

7. 恢复写操作
打开数据库的写功能,去除 Service 层的写拦截提示

8. 清除冗余数据
按照旧的哈希算法,也就是uid%3,使用 delete 语句对冗余数据进行删除

总结
优点:避免了长时间的停服,停写期间用户可以登陆,可以查看自己的数据,可以做其他非DB写入性活动

缺点:类似方案一,造成了时间压力, 必须在指定的时间内完成迁移,且不能出错,每一步都要有回滚预案

五 日志记录

参考:MySQL 数据库平滑扩容方案剖析 - 第三篇

  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值