随着DB的数据规模增长,在没有Proxy中间件参与分片的情况下,正常需要进行数据的拆分。拆分的方法,可分为 水平拆分 和 垂直拆分。
水平拆分,顾名思义,将数据表从一张拆分成多张,表结构保持不变。
垂直拆分,指的是更改表结构,将数据列进行拆分。如下图示:

拆库,是水平拆分的一种方式,具体细节后续文章说明。
我们今天的案例,针对的是已经拆好库的实例。我们要完成从单实例多DB的模式,迁移为多实例单DB的模式,以减轻单实例上的业务压力,我们把这种操作称之为 “物理拆分”。
案例场景:
假设我们实例1(10.1.1.1)中有2个DB,order_01 和 order_02, 当前针对每个DB绑定了内部DNS: order_01.mysql.cloud.rds.com , order_02.mysql.cloud.rds.com ,当前两个DNS都指向10.1.1.1。
我们现在来把实例1中的order_02拆分到实例2(10.1.1.2)中。

请大家思考下,在不中断order_01服务的情况下,如何安全地完成此次迁移?
给大家参考我们公司的做法:
我们提前准备个DB Proxy,需支持 连接转发 (目前我司自研,开源可参考Kingshard)。
迁移步骤:
1. 从 10.1.1.1 同步DB order_02 至 10.1.1.2 中 (使用MySQL replicate_wild_do_table过滤)。
2. 切换前完成数据比对,可使用pt-table-checksum或mk-table-checksum。
3. 使用DB Proxy, 配置请求先转发至10.1.1.1,将order_02.mysql.cloud.rds.com指向 DB Proxy(假设IP为10.1.1.3)。(理论上,在10.1.1.1上只能看到10.1.1.3连接到order_02)

4. 在10.1.1.1上抓取连接,持续kill非10.1.1.3的连接连到10.1.1.1的order_02库。(客户端可能有长期的DNS缓存)
5. 短暂停止DB Proxy, kill 10.1.1.1上proxy的IP连接。(order_02的连接短暂中断)
6. 停止同步,将DB Proxy连接指向10.1.1.3,启动服务。

7. 在10.1.1.1上,将order_02上所有表进行rename,防止残存客户端连接旧DB。
8. 静默观察一段时间后(默认3天),在10.1.1.1上drop database order_02。
目前,第5、6会短暂影响业务,通过自动化手段,可缩短影响时间至5s内。
如果你有更好的思路,欢迎大家留言!
我司长期招聘 RDS For MySQL 开发(golang方向),专注容器云技术,有兴趣请公众号留言给我。




