当前位置:网站首页>线上数据库迁移的几种方法
线上数据库迁移的几种方法
2022-07-04 18:00:00 【Koikoi123】
互联网系统,经常会有数据迁移的需求。系统从机房迁移到云平台,从一个云平台迁移到另一个云平台,系统重构后表结构发生了变化,分库分表,更换数据库选型等等,很多场景都需要迁移数据。
在互联网行业,很多系统的访问量很高,即便在凌晨两三点也有一定的访问量。由于系统数据迁移,导致服务暂停几分钟,是很难被业务方接受的!本文我们就来聊一下,在用户无感知的前提下,如何设计不停机数据迁移方案!
数据迁移过程我们要注意哪些关键点呢?第一,保证迁移后数据准确不丢失,即每条记录准确而且不丢失记录;第二,不影响用户体验(尤其是访问量高的C端业务需要不停机平滑迁移);第三,保证迁移后的性能和稳定性。
传统技术方案
传统方案一般由DBA来做,DBA先停止数据库的使用,然后书写迁徙脚本把数据导出到一个中间文件。然后再书写导入脚本,导入目标库。
传统方案的缺点
- 数据库会停止服务几小时甚至几天,应用程序无法使用,在一些行业应用中基本不可接受。
- 不能满足异构数据的迁徙,如果oralce或sqlservcer和mysql的数据结构不一样,有着比较复杂的映射关系,需要做数据转换,不能满足迁徙。
挂从库
在主库上建一个从库。从库数据同步完成后,将从库升级成主库(新库),再将流量切到新库。这种方式适合数据结构不变,而且空闲时间段流量很低,允许停机迁移的场景。一般发生在平台迁移的场景,如从机房迁移到云平台,从一个云平台迁移到另一个云平台。大部分中小型互联网系统,空闲时段访问量很低。在空闲时段,几分钟的停机时间,对用户影响很小,业务方是可以接受的。所以我们可以采用停机迁移的方案。步骤如下:
1,新建从库(新数据库),数据开始从主库向从库同步。
2,数据同步完成后,找一个空闲时间段。为了保证主从数据库数据一致,需要先停掉服务,然后再把从库升级为主库。如果访问数据库用的是域名,直接解析域名到新数据库(从库升级成的主库),如果访问数据库用的是IP,将IP改成新数据库IP。
3,最后启动服务,整个迁移过程完成。
这种迁移方案的优势是迁移成本低,迁移周期短。缺点是,切换数据库过程需要停止服务。
双写
老库和新库同时写入,然后将老数据批量迁移到新库,最后流量切换到新库并关闭老库读写。
这种方式适合数据结构发生变化,不允许停机迁移的场景。
一般发生在系统重构时,数据结构会发生变化,如表结构改变或者分库分表等场景。有些大型互联网系统,平常并发量很高,即便是空闲时段也有相当的访问量。几分钟的停机时间,对用户也会有明显的影响,甚至导致一定的用户流失,这对业务方来说是无法接受的。所以我们需要考虑一种用户无感知的不停机迁移方案。以笔者之前经历的用户系统重构为例,聊一下具体方案。当时的场景是这样的,用户表记录数达到3000万时,系统性能和可维护性变差,于是我们将用户中心从单体工程中拆分出来并做了重构,重新设计了表结构,而且业务方要求不停机上线!下面是我们当时的方案,步骤如下:
- 代码准备。在服务层对用户表进行增删改的地方,要同时操作新库和老库,需要修改相应的代码(同时写新库和老库)。准备迁移程序脚本,用于做老数据迁移。准备校验程序脚本,用于校验新库和老库的数据是否一致。
- 开启双写,老库和新库同时写入。注意:任何对数据库的增删改都要双写;对于更新操作,如果新库没有相关记录,需要先从老库查出记录,将更新后的记录写入新库;为了保证写入性能,老库写完后,可以采用消息队列异步写入新库。
- 利用脚本程序,将某一时间戳之前的老数据迁移到新库。注意:1,时间戳一定要选择开启双写后的时间点(比如开启双写后10分钟的时间点),避免部分老数据被漏掉;2,迁移过程遇到记录冲突直接忽略(因为第2步的更新操作,可能已经把记录拉到了新库);3,迁移过程一定要记录日志,尤其是错误日志,如果有填写失败的情况,我们可以通过日志恢复数据,以此来保证新老库的数据一致。
- 第3步完成后,我们还需要通过脚本程序检验数据,看新库数据是否准确以及有没有漏掉的数据
- 数据校验没问题后,开启双读,起初给新库放少部分流量,新库和老库同时读取。由于延时问题,新库和老库可能会有少量数据记录不一致的情况,所以新库读不到时需要再读一遍老库。逐步将读流量切到新库,相当于灰度上线的过程。遇到问题可以及时把流量切回老库
- 读流量全部切到新库后,关闭老库写入(可以在代码里加上热配置开关),只写新库
- 迁移完成,后续可以去掉双写双读相关无用代码。

利用数据同步工具
我们可以看到上面双写的方案比较麻烦,很多数据库写入的地方都需要修改代码。有没有更好的方案呢?我们还可以利用Canal,DataBus等工具做数据同步。以阿里开源的Canal为例。

上面是Canal的原理图
- Canal模拟mysql slave的交互协议,把自己伪装成mysql的从库
- 向mysql master发送dump协议
- mysql master收到dump协议,发送binary log给slave(canal)
- canal解析binary log字节流对象,根据应用场景对binary log字节流做相应的处理
所以上面的用户系统数据迁移,就不需要开启双写了,服务层也不需要编写双写的代码,直接用Canal做增量数据同步即可。相应的步骤就变成了:
- 代码准备。准备Canal代码,解析binary log字节流对象,并把解析好的用户数据写入新库。准备迁移程序脚本,用于做老数据迁移。准备校验程序脚本,用于校验新库和老库的数据是否一致。
- 运行Canal代码,开始增量数据(线上产生的新数据)从老库到新库的同步。
- 利用脚本程序,将某一时间戳之前的老数据迁移到新库。注意:1,时间戳一定要选择开始运行Canal程序后的时间点(比如运行Canal代码后10分钟的时间点),避免部分老数据被漏掉;3,迁移过程一定要记录日志,尤其是错误日志,如果有些记录写入失败,我们可以通过日志恢复数据,以此来保证新老库的数据一致。
- 第3步完成后,我们还需要通过脚本程序检验数据,看新库数据是否准确以及有没有漏掉的数据
- 数据校验没问题后,开启双读,起初给新库放少部分流量,新库和老库同时读取。由于延时问题,新库和老库可能会有少量数据记录不一致的情况,所以新库读不到时需要再读一遍老库。逐步将读流量切到新库,相当于灰度上线的过程。遇到问题可以及时把流量切回老库
- 读流量全部切到新库后,将写入流量切到新库(可以在代码里加上热配置开关。注:由于切换过程Canal程序还在运行,仍然能够获取老库的数据变化并同步到新库,所以切换过程不会导致部分老库数据无法同步新库的情况)
- 关闭Canal程序
- 迁移完成
此外,对于数据结构不改变的不停机数据迁移,也可以利用Canal处理。除了第3步DBA可以直接利用工具做老数据的迁移,其他步骤基本和上面一样。
阿里云的数据传输服务DTS
数据传输服务(Data Transmission Service,简称DTS)是阿里云提供的一种支持 RDBMS(关系型数据库)、NoSQL、OLAP 等多种数据源之间数据交互的数据流服务。DTS提供了数据迁移、实时数据订阅及数据实时同步等多种数据传输能力,可实现不停服数据迁移、数据异地灾备、异地多活(单元化)、跨境数据同步、实时数据仓库、查询报表分流、缓存更新、异步消息通知等多种业务应用场景,助您构建高安全、可扩展、高可用的数据架构。
优势:数据传输(Data Transmission)服务 DTS 支持 RDBMS、NoSQL、OLAP 等多种数据源间的数据传输。它提供了数据迁移、实时数据订阅及数据实时同步等多种数据传输方式。相对于第三方数据流工具,数据传输服务 DTS 提供更丰富多样、高性能、高安全可靠的传输链路,同时它提供了诸多便利功能,极大得方便了传输链路的创建及管理。
个人理解:就是一个消息队列,会给你推送它包装过的sql对象,可以自己做个服务去解析这些sql对象。
阿里文档快速入口:https://help.aliyun.com/product/26590.html
免去部署维护的昂贵使用成本。DTS针对阿里云RDS(在线关系型数据库)、DRDS等产品进行了适配,解决了Binlog日志回收,主备切换、VPC网络切换等场景下的订阅高可用问题。同时,针对RDS进行了针对性的性能优化。出于稳定性、性能及成本的考虑,推荐使用。
附datagrip导出数据
边栏推荐
- Detailed explanation of the binary processing function threshold() of opencv
- YOLOv5s-ShuffleNetV2
- Generate XML elements
- HDU 1097 A hard puzzle
- Unity adds a function case similar to editor extension to its script, the use of ContextMenu
- Safer, smarter and more refined, Chang'an Lumin Wanmei Hongguang Mini EV?
- 基于NCF的多模块协同实例
- Unity给自己的脚本添加类似编辑器扩展的功能案例ContextMenu的使用
- 自由小兵儿
- Leetcode fizzbuzz C # answer
猜你喜欢

从实时应用角度谈通信总线仲裁机制和网络流控

Opencv functions and methods related to binary threshold processing are summarized for comparison and use
![[release] a tool for testing WebService and database connection - dbtest v1.0](/img/4e/4154fec22035725d6c7aecd3371b05.jpg)
[release] a tool for testing WebService and database connection - dbtest v1.0

联想首次详解绿色智城数字孪生平台 破解城市双碳升级难点

node_exporter部署

【问题】druid报异常sql injection violation, part alway true condition not allow 解决方案

A method of using tree LSTM reinforcement learning for connection sequence selection

The 300th weekly match of leetcode (20220703)

Go微服务(二)——Protobuf详细入门

FPGA timing constraint sharing 01_ Brief description of the four steps
随机推荐
OpenCV的二值化处理函数threshold()详解
SSRS筛选器的IN运算(即包含于)用法
Lm10 cosine wave homeopathic grid strategy
Use canal and rocketmq to listen to MySQL binlog logs
Introduction to polyfit software
《看完就懂系列》字符串截取方法substr() 、 slice() 和 substring()之间的区别和用法
MySQL数据库基本操作-DDL | 黑马程序员
Shell programming core technology "I"
Generate XML elements
2019年蜀山区第十五届青少年信息学竞赛
Is the securities account opened by qiniu safe?
Detailed explanation of the binary processing function threshold() of opencv
The CDC of sqlserver can read the data for the first time, but it can't read the data after adding, deleting and modifying. What's the reason
HDU 1372 & POJ 2243 Knight Moves(广度优先搜索)
C#实现定义一套中间SQL可以跨库执行的SQL语句(案例详解)
To sort out messy header files, I use include what you use
在线文本行固定长度填充工具
性能优化之关键渲染路径
Nebula importer data import practice
[uniapp] uniapp development app online Preview PDF file