后端存储实战课
李玥
美团高级技术专家
44005 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 30 讲
结束语 (1讲)
后端存储实战课
15
15
1.0x
00:00/00:00
登录|注册

20 | 如何在不停机的情况下,安全地更换数据库?

针对一般情况的数据
针对订单数据
下线旧库
停止对比程序,改为只写新库
逐步切换读请求到新库
数据一致性验证
开启订单服务的双写开关
稳定新版订单服务
改造订单服务
实现两个异构数据库之间的数据实时同步
数据复制到新库
数据实时同步
每一步都是可逆的
思考题
对比和补偿程序
订单库迁移方案
设计迁移方案
墨菲定律
如何在不停机的情况下,安全地更换数据库

该思维导图由 AI 生成,仅供参考

你好,我是李玥。
随着我们的系统规模逐渐增长,总会遇到需要更换数据库的问题。我们来说几种常见的情况。
对 MySQL 做了分库分表之后,需要从原来的单实例数据库迁移到新的数据库集群上。
系统从传统部署方式向云上迁移的时候,也需要从自建的数据库迁移到云数据库上。
一些在线分析类的系统,MySQL 性能不够用的时候,就需要更换成一些专门的分析类数据库,比如说 HBase。
更换数据库这个事儿,是一个非常大的技术挑战,因为我们需要保证整个迁移过程中,既不能长时间停服,也不能丢数据。
那么,今天这节课我们就来说一下,如何在不停机的情况下,安全地迁移数据更换数据库。

如何实现不停机更换数据库?

我们都知道墨菲定律:“如果事情有变坏的可能,不管这种可能性有多小,它总会发生。”放到这里呢,也就是说,我们在更换数据库的过程中,只要有一点儿可能会出问题的地方,哪怕是出现问题的概率非常小,它总会出问题。
实际上,无论是新版本的程序,还是新的数据库,即使我们做了严格的验证测试,做了高可用方案,刚刚上线的系统,它的稳定性总是没有那么好的,需要一个磨合的过程,才能逐步达到一个稳定的状态,这是一个客观规律。这个过程中一旦出现故障,如果不能及时恢复,造成的损失往往是我们承担不起的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

如何在不停机的情况下,安全地更换数据库? 本文介绍了在系统规模逐渐增长的情况下,需要更换数据库是一个常见的挑战。作者强调了设计迁移方案时的可逆性,以确保在出现问题时能够快速回滚到上一个步骤。以订单库为例,详细阐述了迁移方案的设计和实施过程,包括数据复制、实时同步、改造订单服务、稳定运行验证等步骤。在迁移完成后,介绍了如何实现对比和补偿程序,以保证新旧两个库的数据一致性。总的来说,提供了一套完整的迁移数据库的流程和方法,为读者提供了宝贵的技术指导。 设计在线切换数据库的技术方案,首先要保证安全性,确保每一个步骤一旦失败,都可以快速回滚。此外,还要确保迁移过程中不丢数据,这主要是依靠实时同步程序和对比补偿程序来实现。复杂的切换过程的要点总结如下: 1. 上线同步程序,从旧库中复制数据到新库中,并实时保持同步; 2. 上线双写订单服务,只读写旧库; 3. 开启双写,同时停止同步程序; 4. 开启对比和补偿程序,确保新旧数据库数据完全一样; 5. 逐步切量读请求到新库上; 6. 下线对比补偿程序,关闭双写,读写都切换到新库上; 7. 下线旧库和订单服务的双写功能。 思考题提出了一个挑战,即如何修改迁移方案,让由双写切换为单写新库这一步也能做到快速回滚。这激发了读者的思考和讨论。 总的来说,本文提供了有关数据库迁移的详细流程和方法,强调了安全性和数据一致性的重要性,为读者提供了宝贵的技术指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端存储实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(36)

  • 最新
  • 精选
  • 李玥
    置顶
    Hi,我是李玥。 这里回顾一下上节课的思考题: 在我们这种数据同步架构下,如果说下游的某个同步程序或数据库出了问题,需要把 Binlog 回退到某个时间点然后重新同步,这个问题该怎么解决? 这个问题的解决方案是这样的。如果说,下游只有一个同步程序,那直接按照时间重置Canal实例的位点就可以了。但是,如果MQ的下游有多个消费者,这个时候就不能重置Canal里的位点了,否则会影响到其它的消费者。正确的做法是,在MQ的消费订阅上按照时间重置位点,这样只影响出问题的那个订阅。所以,这种架构下,MQ中的消息,最好将保存时间设置得长一些,比如保留3天。
    2020-04-13
    1
    34
  • 等风来🎧
    老师,这个热切开关具体什么方式实现呢?

    作者回复: 这个一般都是通过编码来实现的。具体触发的方法,可以对外暴露一个可供调用的接口,或者通过动态配置下发等方式来触发。

    2020-05-31
    3
    10
  • nfx
    抱歉上个留言没说说清楚,请问老师线上大表怎么在不影响业务的情况下增加字段? 我能想到的一个办法是在从库增加字段,等从库同步追上来的时候切换主从。 请问还有没有其他办法? 另外线上扩容怎么做? 是不是和这节课更换数据库的方法一样? 加个从库,同步追上来后分库分表?

    作者回复: 大表加字段过程中会锁表,期间所有写操作都会阻塞。如果能接受的话,直接加还是最方便的。 你提的主从切换的方式,我没有试过,理论上也是可行的。但需要特别注意切换过程中的数据一致性。 线上扩容,相当于更换数据库,建议参照这节课中的方法操作。

    2020-05-25
    3
    6
  • 借楼请教一下李老师,无限层级(每条记录都对应一个父id)怎样设计能够快速查询,之前设计是存一个path字段,用like查询,总感觉这样设计不优雅。

    作者回复: 可以再把问题具体话一下么?我们可以一起来讨论一下。

    2020-04-11
    4
    4
  • me不是一个人战斗
    对于双写阶段,会不会存在两份数据id不一致的情况(比如mysql的自增ID),如果下游有依赖这个表的ID,一旦切换就没办法回退了

    作者回复: 这种建议以一边的自增ID为准。

    2020-04-28
    2
  • 百威
    有个问题,既然有比对和补偿程序,可不可以不使用数据实时同步。首先上线观察双写和补偿程序,没问题后先进行数据从旧到新的快照复制,然后开启双写,因有缝衔接而丢失的数据通过补偿程序来做……求教~

    作者回复: 考虑到很难实现一个完美的对比补偿程序,还是建议不要这么做。

    2020-04-21
    2
  • nfx
    请问老师,修改线上数据库表结构怎么处理? 我原来方案是建个新表,把旧数据倒过去,然后新旧表分别改名。 但数据一致问题比较麻烦,改名过程中也容易出错

    作者回复: 这个问题是非常难处理的,所以,一般来说很少去删除表的字段,只增加字段。这样,新表能够兼容旧表,也就不用迁移数据了。

    2020-05-22
    2
    1
  • 彼得.林
    阿里的自建mysql同步到RDS,需要做些什么工作呢?是不是较检程序也是必须的

    作者回复: 这里面也要考虑实施成本VS数据重要程度来决策。

    2020-05-11
    2
  • hllllllllll
    在16年去o时设计的一个方案和这个很相似。需要将56亿oracle的财务数据迁移到mysql中并保证一直提供稳定的线上服务。方案主要涉及以下几点: 1.设计同步worker以6亿/天的速度同步至mysql,预先按照1000的间隔生成560w个任务,用于保证数据同步不丢失。 2.mysql业务数据库库为了防止和oracle中id碰撞,设计id生成器 其中,前三位为库编号; 3.因为高达100w/分钟的事务量,设计了前置防重表+任务表(按照uuid分库),用于防重、规避热点和异步增加吞吐量; 4.业务数据库通过在前置库生成的id分库,同时会异步同步至es; 5.原接口服务改造,写老库数据和发送mq在一个事务(mq挂了会影响服务)。提供新接口服务写新库并发mq; 6.接收端消费mq并根据标示同步至老库或新库; 7.提前定义好一个阈值单号,比如当前数据已经累积到57亿,那我们可以根据增速估算一个阈值58亿。在上线后只有58亿以后的数据会通过mq同步至老库的。以前的数据都由worker同步(在适当时候:如目前单号已超过58亿,生成另外20w个任务,并开始执行另外两亿数据的同步,期间新库会缺少这两亿数据); 8.在mq同步稳定一段时间后,用新接口灰度替代老接口,在整体稳定后全量切换至新接口,并用mq同步老库。
    2020-05-05
    4
    62
  • 菠萝吹雪—Code
    无知者总觉得这样做麻烦,智者满满都是细节
    2020-04-15
    2
    23
收起评论
显示
设置
留言
36
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部