如何高效地进行大规模数据迁移?

article/2025/8/19 0:56:03

导读

我们在做一次系统业务模型重构的时候,往往会遇到把旧模型表中的数据迁移到新模型表中,如果这时候,我们旧表中的数据规模已达到千万级以上,那么,这个从旧表迁移到新表的过程会非常漫长,而业务仍需快速推进,业务方接受不了这么高的迁移成本,此时,开发同学就会想:既然业务不允许停滞,但是,又不得不将大规模的数据迁移新模型表中。那么,为了保证对业务影响最小,更快完成数据迁移,一批插入多少条记录到新表的效率最高呢?

今天,我就以用户中心这个系统中的用户表为例,详细讲解一下一条Insert语句的插入过程,从而找出影响一条记录插入性能的因素,最后,回答一批插入多少条记录到新表效率最高?

插入过程

假设我们使用的用户表结构如下:

CREATE TABLE `user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`user_id` int(8) DEFAULT NULL COMMENT '用户id',`user_name` varchar(29) DEFAULT NULL COMMENT '用户名',`user_introduction` varchar(498) DEFAULT NULL COMMENT '用户介绍',`sex` tinyint(1) DEFAULT NULL COMMENT '性别',`age` int(3) DEFAULT NULL COMMENT '年龄',`birthday` date DEFAULT NULL COMMENT '生日',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

现在,假设这张表是我们的新用户模型表,然后,我们要将旧模型表中的的3000w条用户记录插入新模型表,采用分批插入的方式,即一次8000条,那么,这个插入的过程如下:

在这里插入图片描述
图中,为了重点描述插入记录的过程,所以,我只插入了4条记录:
< 1, 10001, Jack, …>
< 2, 10002, Nancy, …>
< 3, 10003, Jack, …>
< 4, 10004, John, …>
这4条记录的插入过程大致如下:

  1. 将4条记录的插入操作和相应的删除操作写入Undo Log。
  2. 将4条记录的插入操作写入Redo Log。
  3. 将4条记录写入Bin Log(行模式)。
  4. 读取redo log,将4条记录写入索引和数据文件Data File。

其中,由于写入上面undo log、redo log、bin log和data file这4个文件,除了data file是异步写,其他3个都是同步写,且都为磁盘写,势必影响插入记录的性能,所以,MySQL针对这3个文件的同步写做了一系列优化,保证插入记录的性能。

现在我就从性能优化的角度,讲解一下MySQL是如何优化这3个文件的写入的?讲解完后,我将回答本章标题的问题:一批插入多少条记录到新表的效率最高呢?

  • Undo Log
    对MySQL事务有一定了解的同学,应该知道MySQL的事务回滚就依赖这个log文件,所以,关于undo log的内容,我会在《我的事务执行好慢,怎么办?》中详细讲解。

  • Redo Log
    关于redo log,你可能会问:MySQL为什么要记录这个log?

从数据可靠性来看,以上面的插入记录为例,如果没有第2步,MySQL执行到第4步,此时,刚好完成第1和2条记录插入,插入第3条记录时,MySQL宕机了,那么,将导致第3和4条记录丢失,所以,MySQL为了保证在重启机器时,能够再将3和4两条记录重新插入表中,将4条记录的插入操作全部写入redo log,那么,在重启机器后,MySQL就能从redo log中找到3和4两条记录,将这两条记录重新插入表中。

结构

现在,我们再来看一下redo log的结构:

在这里插入图片描述
redo log由多组文件组成,每组对应一个文件,每个文件大小一致。其中,文件以ib_logfile[number]命名。如上图,有4组文件,ib_logfile1到ib_logfile4。同时,ib_logfile有如下特点:

  1. 每个ib_logfile文件存的是记录的操作信息。
  2. ib_logfile之间是循环依赖,如上图,在所有文件写满后,新的操作信息重新写入第一个ib_logfile。

一共有多少个组,以及每个文件大小多大,可以通过参数配置。主要参数如下:
innodb_log_files_in_group:分几个组。
innodb_log_file_size:每组对应的文件的大小。
所以,redo log的总大小 = innodb_log_files_in_group * innodb_log_file_size

写入

我以上面插入4条记录为例,讲解一下redo log的写入过程:

在这里插入图片描述
我以船运货来模拟这个写入的过程,主要包含4个步骤:

  1. 将4条记录的插入操作写入缓冲区buffer,如上图(1)中的黄色小方块为这4条记录的插入操作组成的一组。图中最左边的码头代表buffer。
  2. 如果buffer满了,从buffer中读取已有的操作,开始IO总线传输这些操作,准备把它们写入redo log文件。如上图(1),绿色小方块代表buffer中已有的操作,表示buffer满了,见图(2),小船运输绿色小方块代表IO总线传输。再执行步骤1,将4条记录的插入操作写入buffer。如图(2)中黄色小方块放到最左边的码头。
  3. 将buffer中已有的操作写入redo log文件。如上图(3),中间的码头代表redo log文件,绿色小方块准备放到该码头上。
  4. 如果redo log文件满了,MySQL会执行我在《导读》中的那张图中写redo log之后的动作,将文件中的操作的记录刷到数据文件中。如上图(3),粉色小方块代表redo log中的操作,表示redo log满了,见图(4),小船运输粉色小方块到最右边的码头,最右边的码头代表数据文件。再执行步骤3,结合上面讲到的redo log的结构,从第一个文件ib_logfile1开始写4条记录的插入操作。如图(4)中绿色小方块放到中间的码头。

这里,其实是有问题的:如果缓冲区buffer写入成功,但是,之后写入redo log失败,那么,4条记录的操作将全部丢失。

所以,MySQL为了保证buffer和redo log文件的一致性,引入mtr的概念,全称Mini-Transaction,将buffer和redo log操作封装在一个mtr中,这样,就能保证buffer和redo log的写入要么都成功,要么都失败,如果失败的话,记录仍旧保留,可继续写buffer。

关于mtr的详细内容,我将在《MySQL是如何平衡日志写入的性能和数据可靠性的?》讲解。

从上面写入redo log的过程中,我们发现由于MySQL在写redo log文件前,先写buffer,而写buffer是一个内存操作,所以,同步写的性能就有了保障。

这里还有一个问题:插入操作时,如果MySQL每次都是等redo log写满,再将log中的所有内容刷到数据文件,那么,redolog很大的话,这样,刷数据文件的性能会很差。那怎么解决呢?

我们看下面这张图:

在这里插入图片描述
MySQL引入了checkpoint的概念,由一个线程定时推进redo log的某个位置,这个位置就叫checkpoint,该位置之前的内容,即图中write position到checkpoint之间的内容,会由另一个线程刷到数据文件。这样,就避免大量的数据刷到数据文件,从而影响插入的性能。ps:MySQL会在write position到checkpoint之间的大小超过redo log总大小的76%就会提前触发刷数据文件的行为。

Bin Log

初步了解MySQL的同学一定知道binlog,它记录了每一条SQL的操作,MySQL主从实例之间的同步就是依靠它来实现的。那么,这里对比redo log,你可能会有一个疑问:redo log用来记录记录操作行为的,bin log也是记录记录操作的,那么,为什么有redo log,还需要bin log?

主要基于两点原因:

  1. redo log是InnoDB特有的日志,其他存储引擎没有这样的日志。而bin log是所有存储引擎都支持的日志。
  2. redo log是固定大小不变的。而bin log是可以不断追加的。如果用redo log来同步记录到从库上,如果出现从库还未拉取redo log上的一些操作,redo log里的这些操作因为日志写满,导致相应操作的记录被刷到数据文件,那么,redo log上针对这些操作的记录将丢失,记录无法同步到从库。

参数配置

现在回到本章标题的那个问题:一批插入多少条记录到新表的效率最高呢?

从本章《插入过程》这一部分中,我们知道,在真正插入记录到数据文件前,会经过3个日志文件的写入:undo log、redo log和bin log,可见,3个日志文件的写入性能是影响整个记录插入性能的关键。

由于undo log和bin log都是可以不断追加的,同时,两者都是顺序写文件,所以,在批量插入记录的时候写这两个文件在性能上不会有太大的影响。

而redo log是有固定大小的,采用的是循环写,所以,批量插入记录的操作,在所有redo log写满后,把redo log中的操作对应的记录刷到数据文件后,会重新从第一个ib_logfile中写记录的批量插入操作,这是一个随机IO,会影响批量插入的性能。

所以,为了不影响批量插入记录的性能,我们可以调整redo log的总大小,即我在讲解redolog结构的时候提到的两个参数:innodb_log_files_in_group和innodb_log_file_size,保证一次批量插入的记录大小小于等于innodb_log_files_in_group * innodb_log_file_size,这样,我们就能减少redo log的随机IO,保证批量插入的性能。

比如:我现在一次批量插入的记录大小为800M,那么,我就要调整innodb_log_files_in_group=10,innodb_log_file_size=80M

具体调整方法如下:

  1. 打开my.cnf配置文件
  2. 设置innodb_log_files_in_group=10
  3. 设置innodb_log_file_size=80M
  4. 重启MySQL

通过上面的参数调整,我们就能保证一次批量插入大量的记录的效率是最高的。

小结

在本章节中,我以一次批量插入大量记录的例子为引线,讲解了Insert批量插入记录的过程,最后,由这个过程分别引出3个日志:undo log、redo log和bin log。重点讲解了redo log。

最后通过redo log的分析,回答了一批插入多少条记录到新表的效率最高呢?这个问题。

希望你在这篇文章中有所收获!


http://chatgpt.dhexx.cn/article/gYQpLG9K.shtml

相关文章

电脑数据怎么迁移?

“最近我的电脑越来越卡&#xff0c;运行程序时还会出现卡死奔溃的现象&#xff0c;陪伴我多年的电脑到了退休的时候了。购买了一台新款的笔记本电脑&#xff0c;打开软件运行多么的流畅&#xff0c;别提多高兴了&#xff01;可是&#xff0c;我想把旧电脑的数据导入到新电脑怎…

数据库整体迁移

1.迁移方法概述: 使用Navicat Premium 分别与源数据库和目标数据库建立连接,然后借助Navicat Premium自带的数据传输功能,实现Oracle数据库的迁移.其实跟从MySQL数据库迁移到oracle数据库是一个套路. O(∩_∩)O~ 听起来,是不是很简单,其实就是很简单!下边我就讲一下具体实现的细…

数据库迁移的方法

数据库迁移的方法 我们今天以mysql为例&#xff0c;讲讲数据库迁移的四种方法。 1、将数据库倒出为sql文件&#xff0c;再重新导入&#xff08;推荐&#xff09;。 首先将mysql数据库锁定&#xff0c;并将内存中的数据写入磁盘。 flush tables with read lock ; 用mysqldump将t…

数据迁移——技术选型

日常我们在开发中&#xff0c;随着业务需求的变更&#xff0c;重构系统是很常见的事情。重构系统常见的一个场景是变更底层数据模型与存储结构。这种情况下就要对数据进行迁移&#xff0c;从而使业务能正常运行。 背景如下&#xff1a;老系统中使用了mongo数据库&#xff0c;由…

Oracle数据迁移MySQL

前言: 现今&#xff0c;Oracle数据迁移MySQL的需求已经越来越普遍&#xff0c;主要的迁移场景大致可以分为三类&#xff0c;第一类是涉及小表以及少量表的一次性迁移&#xff0c;无需进行增量同步&#xff0c;第二类是涉及大表以及多表的一次性迁移&#xff0c;第三类是涉及增…

电脑之间如何迁移数据?数据迁移方法描述

电脑之间如何迁移数据&#xff1f;当更换电脑时&#xff0c;很多人需要做的第一件事&#xff0c;就是将旧电脑的数据通过外置存储设备等拷贝到新电脑上&#xff0c;并且还要在新电脑上重新安装应用程序&#xff0c;步骤繁琐&#xff0c;耗费了大量的时间和精力不说&#xff0c;…

DB数据迁移方案

互联网系统&#xff0c;经常会有数据迁移的需求。系统从机房迁移到云平台&#xff0c;从一个云平台迁移到另一个云平台&#xff0c;系统重构后表结构发生了变化&#xff0c;分库分表&#xff0c;更换数据库选型等等&#xff0c;很多场景都需要迁移数据。 在互联网行业&#xf…

【OceanBase】四种不同的数据迁移方式

前言 OceanBase 已连续 9 年稳定支撑双 11&#xff0c;创新推出“三地五中心”城市级容灾新标准&#xff0c;在被誉为“数据库世界杯”的 TPC-C 和 TPC-H 测试上都刷新了世界纪录。自研一体化架构&#xff0c;兼顾分布式架构的扩展性与集中式架构的性能优势&#xff0c;用一套…

数据迁移介绍

数据迁移方案 数据迁移框架有几个比较有名应用比较广泛的开源项目&#xff1a;阿里datax&#xff0c;apache sqoop以及Pentaho kettle。这三个框架整体上工作原理类似&#xff0c;下面介绍阿里datax数据迁移框架。 对旧系统进行了重构&#xff0c;就需要把原来的数据迁移到新数…

代码技巧——数据迁移方案【建议收藏】

开发工作中&#xff0c;可能会遇到如"大表拆分"、"跨库数据迁移"等场景&#xff0c;本文介绍互联网常见架构下的数据迁移方案及实现&#xff1b; 1. 数据迁移的业务场景 以下是需要数据迁移的场景业务场景&#xff1b; 1.1 大表拆分 由于历史原因&…

【Pytorch】Label Smoothing

理论介绍可以参考 【Inception-v3】《Rethinking the Inception Architecture for Computer Vision》 中的 4.5 Model Regularization via Label Smoothing 本质就是用右边&#xff08;意会下就行&#xff09;的标签替换左边的 one-hot 编码形式&#xff0c;让网络别那么愤青&…

关于label smoothing(标签平滑)

目的&#xff1a; label smoothing常用于分类任务&#xff0c;防止模型在训练中过拟合&#xff0c;提高模型的泛化能力。 意义&#xff1a; 对于分类问题&#xff0c;我们通常使用one-hot编码&#xff0c;“非黑即白”&#xff0c;标签向量的目标类别概率为1&#xff0c;非目标…

【AI面试】hard label与soft label,Label Smoothing Loss 和 Smooth L1 Loss

往期文章: AI/CV面试,直达目录汇总【AI面试】NMS 与 Soft NMS 的辨析【AI面试】L1 loss、L2 loss和Smooth L1 Loss,L1正则化和L2正则化在一次询问chatGPT时候,在他的回答中,由smooth L1联想提到了Label Smoothing Loss 。我把问题贴到下面,和chatGPT的回答,供你参考。不…

标签平滑(label smoothing)

目录 1.标签平滑主要解决什么问题&#xff1f; 2.标签平滑是怎么操作的&#xff1f; 3.标签平滑公式 4.代码实现 标签平滑&#xff08;label smoothing&#xff09;出自GoogleNet v3 关于one-hot编码的详细知识请见&#xff1a;One-hot编码 1.标签平滑主要解决什么问题&…

指数平滑法 Exponential Smoothing

指数平滑法 Exponential Smoothing 指数平滑法&#xff0c;用于中短期经济发展趋势预测。 1 时间序列分析基础知识 1.1 时间序列分析前提假设 时间序列分析一般假设我们获得的数据在时域上具有一定的相互依赖关系&#xff0c;例如股票价格在t时刻很高&#xff0c;那么在t1时…

label smoothing(标签平滑)

label smoothing是一种在分类问题中&#xff0c;防止过拟合的方法。 label smoothing&#xff08;标签平滑&#xff09; 交叉熵损失函数在多分类任务中存在的问题label smoothing&#xff08;标签平滑&#xff09;参考资料 交叉熵损失函数在多分类任务中存在的问题 多分类任务…

When Does Label Smoothing Help?

原文链接&#xff1a;When Does Label Smoothing Help? Hinton老师的这篇paper&#xff0c;解释了标签平滑策略在什么情况下是有效的&#xff1f; 摘要 通过从hard targets加权平均得到的soft targets&#xff0c;可以显著提升多分类神经网络的泛化性和训练速度。这种标签平…

【NLP基础理论】02 N-grams语言模型和Smoothing

注&#xff1a; Unimelb Comp90042 NLP笔记 相关tutorial代码链接 N-grams Language Model &#xff08;N-grams语言模型&#xff09; 目录 N-grams Language Model &#xff08;N-grams语言模型&#xff09;1.1 Deriving n-gram language models&#xff08;推导&#xff0…

Good-Turning Smoothing介绍及推理

在介绍Good-Turning Smoothing之前&#xff0c;我们可以先看一个有趣的例子&#xff1a; 假设你在钓鱼&#xff0c;已经抓到了18只鱼&#xff1a; 10条鲤鱼&#xff0c;3条黑鱼&#xff0c;2条刀鱼&#xff0c;1条鲨鱼&#xff0c;1条草鱼&#xff0c;1条鳗鱼… Q1&#xff1a;…

关于label smoothing的理解

背景介绍 提到label smoothing&#xff08;标签平滑&#xff09;&#xff0c;首先介绍一下什么是hard label和soft label. 简单来说&#xff0c;hard label就是非1即0&#xff0c;不存在既可能是A也可能是B的情况&#xff0c;soft label则不同&#xff0c;它并不要求所有的“精…