关于mysql:实战篇单库单表变更成多库多表

59次阅读

共计 2755 个字符,预计需要花费 7 分钟才能阅读完成。

大家好,我是七淅(xī)。

如题目所说,本文会联合我本人的亲身经历,介绍 3 局部内容:

  1. 线上单库单表变更到多库多表的各个实现计划
  2. 计划优劣比照
  3. 对于历史存在的单表,并且它们 不须要 变成多表,须要怎么解决

先下个论断,没有百分百完满的计划,技术计划永远要联合产品业务来设计

以下举例的计划也只是较为通用的做法,具体细节是能够依据业务场景进行变动调整的。

只有可能满足业务需要,就是好计划,不要为了秀技术而疏忽业务。

看完这篇文章,如果前面有人问你,对于变更到多库多表的计划问题,那你能够和他谈笑自若了。

好了,上面我说下我这边的业务背景,和大家解释分明为什么须要多库多表。前面会引申出计划的,莫急。

1. 业务背景

有一个 在线上运行着 的数据库,假如是 user 库,库中 只有 1 张单表。

当初有个新需要,该需要的性能有肯定的申请量和数据量。

其中数据量初期是百万级,思考到业务减少,增长到千万、上亿都是有可能的。所以从数据量上看,单库单表不适合

Q1:如果只是数据量问题,那用单库多表行不行?
A1:行。
Q2:那为什么还用多库多表呢?
A2:因为一个数据库的连贯数量是无限的,怕翻车

下面有介绍业务有肯定的申请量,放心一个库来解决的话,万一哪天网络不好 / 慢查 / 该表业务有突发性流动等状况呈现。

一不小心就把连接数占满了,那就间接翻车了。

加上我司对多库多表的基建比拟成熟,所以我这边就间接上多库多表了。

Q3:既然如此,后期先上单库多表,等量上来后再多库多表行不行?
A3:能够。然而到时再来一次太累了。

比方再来一次会经验以下事件:

  • 每天须要看看数据监控
  • 有没有到瓶颈
  • 到时再次变更时,开发运维测试业务的排期和执行
  • 业务变动:说好的下个季度大推,后果提前到下一个月进行,此时数据库能不能扛住,扛不住革新工夫是否短缺?

所以,咱们要不还是一步到位吧。

滴,七淅揭示你:看到这,如果有人问你单库多表和多库多表的应用场景,你应该晓得怎么施展了吧

2. 历史数据处理

我先说下对历史数据处理,篇幅较少。

这里的内容对应文章结尾的第三点:对于历史存在的单表,并且它们 不须要 变成多表,须要怎么解决

这里能够有两种解决形式。

咱们晓得,历史数据在 user 库,假如业务须要减少到 8 个库,并且新表须要在这 8 个库中

2.1 形式一

新增 user_0、user_1、...、user_7 共 8 个库,应用 rename 命令,将 user 库的表迁徙到 user_0 库中,最初将 user 库删掉即可。

rename 命令其实就是重新命名,实现剪切数据的成果,而不是复制。当然要用复制的形式迁徙数据也是能够的,但咱们这边没用。

reanme 命令应用如下:

rename table user.table_name to user_0.table_name;

2.2 形式二

新增 user_0、user_1、...、user_7 共 8 个库,user 库数据不动,持续应用。

至于选哪种形式,大多状况下,我集体认为都能够,但如果历史表自身申请就很高,那能够思考用形式二,防止 0 号库压力太大。

我这边是抉择的形式一。当用户要拜访历史表时,指定路由到 0 号库就好了,顺便省下一台数据库的钱,真香

3. 变更计划

计划这块内容,我会基于形式一的历史数据处理形式来讲。

首先,先不思考任何计划,我把最简略的,变更到多库多表的操作按程序列举一下:

  1. 批改服务连贯数据库的配置,业务代码编写
  2. 减少 user 0-7 号数据库
  3. 将 user 库旧表数据迁徙到新增 user_0 库
  4. 部署服务

然而如果依照上述做法,在第 3、4 步执行期间,如果用户拜访原 user 库的数据会有问题。

具体来说:user 库的旧数据此时曾经通过 rename,迁徙到了 user_0 库,但因为部署还没部署实现,连贯数据库的配置没有更新。

所以申请依旧会跑去 user 库查问,导致查不到数据,后续业务逻辑没法程序继续执行。

用户也会纳闷:「这个中央之前进来都有数据的呀,怎么当初全空了?」

所以,须要确定正当的降级计划,最大水平缩小对业务和用户的影响,

3.1 计划一

这是最简略的形式。

看监控,筛选没有流量的时候,进行 db 变更和服务部署。

当然,监控也只是过来的状况,保不准性能上线那天就始终有流量没停歇过呢。

所以再求稳一点的话,能够发个布告,告知用户 xx 性能会在 xxx 时间段进行保护,期间不可拜访。

如果有玩农药(王者光荣)的敌人应该很相熟吧,每次版本更新都须要停服,就是这样的成果哈。

最初在实现之后,进行回归测试和新功能测试,看看性能是否失常。

如果失常那就能够去睡觉了,有问题就持续改 bug 解决;

如果评估没法在布告所说的截止工夫解决,那就只能进行回滚,改日再(jia)战(ban)。

PS:如果须要对历史数据进行分库分表的话,最好进行数据量的比照测验。因为我这边不波及对历史数据进行分库分表,所以这步就省了。

3.2 计划二

这个计划会简单很多,开发量也会很大。

我这边就只说关键步骤,具体细节就没法一一写了。因为要写的话又多出几千字的内容,篇幅太长,我预计也没多少人有急躁看完。

那话说回来,这个计划最大的益处就是业务性能不必停用,所以也就不必熬大夜了。

那要怎么做呢?

3.2.1 历史单表数据处理

1、先把 user 库现有的数据复制一份到 user_0 库。

2、因为 user 库的数据是会被批改和新增的。所以当复制实现后,数据仍旧存在变动,所以须要新增双写逻辑,保障 user_0 库的数据也能同步到变更。

3、对于数据的读写,都反对由开关管制,别离能够控制数据读写是申请到哪个数据库。

4、服务更新实现后,进行两个库的数据一致性比照。都没问题后,开关管制读写数据都申请到 user_0 库

3.2.2 新性能的多表数据处理

因为是新性能,其实不必怎么非凡解决。

为什么这么说呢?

因为咱们部署服务的程序必定是操作数据库的底层服务先公布,公布实现后,才对用到底层服务的应用服务进行公布。

所以作为业务性能入口的应用服务都还没公布,此时是不会有新性能数据达到底层服务的。

要是不能保障这个程序,你想下性能入口凋谢了,用户申请进来后,底层服务发现找不到这个表,是不是就间接报错了?

所以才会有下面说的公布程序,只有保障公布程序没错,那这块新性能的数据是不须要非凡解决。

3.3 计划优劣比照

其实 2 个计划就是互补的,一个计划的长处就是解决了另一个计划的毛病。

七淅用表格总结一下:

长处毛病
计划一操作简略,无需编写简单代码来保障有流量时,业务的失常执行累人,熬大夜太酸爽了;会停用局部业务,影响用户体验
计划二业务不用停用,不影响用户开发成本大

最初,你问我当初是选哪个计划?

那必定是计划一啊,大不了熬一夜嘛。

不然那么麻烦的计划,排期又那么缓和,开发是不可能开发的,这辈子都不可能的。真有什么问题,大不了就人工染指解决,yyds


文章首发公众号:七淅在学 Java,继续原创输入 Java 后端干货。

如果对你有帮忙的话,能够给个赞再走吗

正文完
 0