MySQL批量导入数据时,为何表空间膨胀了N倍

csv导入mysql_如何将上亿条大容量数据导入MYSQL 我有一份数据量达到1,0015,0806条的csv文件,现在需要导入Mysql中。 在我电脑中安装的版本是MYSQL8.0.12,常见的管理工具有:已知的有三种办法: ... 阅读详情
  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
  • GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
  • 作者:叶金荣
  • 文章来源:GreatSQL社区原创

问题缘起

同事在客户现场利用DTS工具,从A实例将数据迁移到B实例过程中,发现几乎稍大点的表在迁移完成后,目标端表空间大小差不多都是源端的3倍,也就是说表空间膨胀了2倍。

排查思路

对这篇文章 《叶问》第16期 有印象的话,应该还能记得,数据迁移(导入导出)过程中,也包括主从复制场景,导致表空间膨胀的原因有几种:

  1. MySQL表默认是InnoDB引擎且目前索引只支持B+树索引,在数据的增删改过程中,会因为page分裂而导致表产生碎片,主从服务器上同张表的碎片率不同也会导致表空间相差很大。
  2. 主库整理过碎片(相当于重建整表),从库则是从原先的未整理的物理备份中恢复出来的。
  3. 两端表结构不一致,如从库可能比主库多索引。
  4. 两端表的行格式不一致,如主库为dynamic,从库为compressed。
  5. 两端字符集不同,例如源端是latin1,目标端是utf8mb4。
  6. 个别云数据库在从库上可能采用特殊的并行复制技术,导致在从库上有更高的碎片率(有个极端的案例,同一个表在主库只有6G,从库上则有将近150G)。
  7. 数据表上没有自增ID作为主键,数据写入随机离散,page频繁分裂造成碎片率很高。

问题发现

顺着上面的思路,逐一排查,看能否定位问题原因。

  1. 因素1,不存在,这是全量迁移场景,不是在日常随机增删改的过程中导致膨胀的。
  2. 因素2,不存在,这是利用DTS工具迁移数据的场景。
  3. 因素3、4、5,不存在,两边表结构一致。
  4. 因素6,不存在,原因同2。
  5. 因素7,不存在,每个表都有自增ID作为主键。

排查到这里,就显得有点诡异了,似乎遇到了玄学问题。不过没关系,我们还需要先了解DTS工具的工作方式,大致如下:

  1. 计算数据表总行数。
  2. 根据batch size,分成多段并行读取数据;例如总共10000行数据,batch size是1000,则总共分为10次读取数据。
  3. 将读取出来的数据拼接成 INSERT...VALUES...ON DUPLICATE KEY UPDATE,因为DTS工具要支持增量迁移数据,所以才加上 ON DUPLICATE KEY UPDATE 子句。
  4. 将拼接后的SQL并行写入到目标端。

初看上述工作过程,似乎也没什么特别之处会导致数据写入后产生大量碎片,从而表空间文件急剧膨胀。

首先,读取数据阶段只涉及到源端,可以先排除了。所以,疑点集中在第3、4两步。

了解InnoDB引擎特点的话应该知道,当InnoDB表有自增ID作为主键时,如果写入的数据总是顺序递增的话,那么产生碎片的概率就会很低。但是,如果写入的数据是离散化的(比如插入的顺序是随机离散的,或者比如插入顺序为1、10000、2、3000、3、5000...这种完全离散无序的),则有极大可能会造成碎片率很高。

按照上述疑点,我们需要确认DTS工具构造的SQL是什么样的,这就需要修改选项 binlog_format = statement,这是为了获取其原生的SQL,row模式下可能就相对不好排查了。然后再次运行DTS工具,查看生成的SQL。

经过排查,终于发现问题所在,原来是DTS工具在拼接SQL时,虽然是分段读取数据,但没有将读取出来的结果集先行排序,造成了拼接后的SQL大概像下面这样的:

INSERT INTO t VALUES (100, ...), (99, ...), (98, ...)...(1, ...);

这种方式写入的话,而且还是并发写入,就会极大概率造成InnoDB data page频繁分裂,所以表空间文件才膨胀到原来的3倍之巨。原因不难理解,就好比排队机制,本来我们是按照身高顺序排,但现在有几位高个子的先排在前面了,那么后来的每次都要让这几个人频繁往后移动才行,这就造成了data page分裂,产生大量碎片。

我用几万条sysbench标准表做测试,采用这种方式写入的话,大概会造成约20%的表空间膨胀率。

问题已然明确,只需要在读取数据拼接插入SQL这个阶段,先行对结果集进行排序,就可以完美解决这个问题了。

并顺手给负责SQL优化器的同学提了个feature request(MySQL bug#109087),希望能在遇到上述倒序INSERT的情况下,自动完成SQL改写,改倒序为正序(或者说,INSERT的顺序和表主键定义的顺序一致,通常都是正序的INT),也就可以完美避开这类风险了。


Enjoy GreatSQL :)

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

捉虫活动详情:https://greatsql.cn/thread-97-1-1.html

社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html

6440

远程数据库数据导入本地:从原理到实战的完整指南 数据迁移是数据库管理和开发中的一项基础且关键的操作,其核心在于将数据从一个存储位置安全、高效地转移到另一个位置。其原理通常涉及逻辑导出(如生成SQL脚本)或物理文件拷贝,旨在满足开发测试、数据分析、备份归档等场景的需求。这项技术的价值在于保障数据一致性、提升运维效率并支持业务连续性。在实际应用中,无论是使用MySQL的mysqldump还是PostgreSQL的pg_dump,都需要重点关注网络连通性、账号权限配置和字符集兼容性等工程实践细节。本文将围绕**mysqldump**和**数据一致性**这两个核 阅读详情

相关推荐

MySQL分库分表后单表数据还是过大怎么办

针对使用ShardingSphere分库分表后MySQL单表数据仍然过大的问题,以下是分步骤的解决方案:首先明确单表数据量过大的具体原因: 2.2 增加分片数量 若当前分片数为,可扩容至或更高,需配合数据迁移工具(如ShardingSphere-Scaling)平滑迁移。 动态分片:设计支持动态扩容的分片规则(如按范围分片时预留分片空间)。 2.3 多维度分片 组合分片策略:例如同时按和分片,避免单维度热点。 **3. 冷热数据分离 3.1 归档历史数据 将历史数据(如3年前订单)迁移至归档

沉修所长,勇逐新机;安而不怠,静而思变 1415

MySQL进程内存一直在涨,怎么办?

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。老叶提醒:本文结合MySQL内存为什么不断增高,怎么让它释放 阅读,收获更多。1.问题开端2.问题分析3.原因及意见1.问题开端工程师反馈数据库服务器内存使用率高,并且之前曾触发告警,登录服务器使用top -u mysql查看进程使用内存信息:发现mysqld进程使用内存达到了61.5%,并有缓慢增长趋势。但是数据库...

老叶茶馆 8908

Excel数据透视表实战:分组折线图制作与动态分析指南

数据可视化是数据分析的关键环节,其核心原理在于将抽象数据转化为直观图形,以揭示趋势、对比差异。在众多图表类型中,折线图因其能清晰展示连续数据随时间或其他序列的变化趋势,而成为趋势分析的利器。其技术价值在于通过视觉编码,将多维数据关系降维呈现,从而辅助决策。在业务分析、运营监控等应用场景中,常需对比不同分组(如产品线、销售区域)在同一时间序列上的表现,这正是分组折线图要解决的核心问题。本文聚焦于利用Excel数据透视表这一强大工具,高效构建动态分组折线图,并深入探讨数据透视表在数据重塑和图表自动化中的实战应用

weixin_29057237的博客 381

MySql 使用索引进行查询优化;常用mysql优化

索引有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引...

Unique-You的博客 3万+

足球赛事数据API:开发者生存指南(附真实踩坑记录)

作为一个既爱看球又爱写代码的老宅男,我这些年用过的足球API比看过的比赛还多。从最初被各种API文档折磨到怀疑人生,到现在能闭着眼睛调接口,中间的血泪史够写本书了。今天就把这些经验(和教训)分享给各位同好,特别是那些正在为"老板要做个足球App"而秃头的同行们。文档清晰免费层可用响应格式规范API-Sports免费额度大方支持GraphQL有中文文档(难得!Sportmonks数据全面有Webhook支持按需付费。

Happy0970的博客 2192

E2000 RGMII0通讯异常问题总结

飞腾E2000 RGMII接YT8521,RGMII0路不通问题。

乌拉大喵喵 1630

mysql data free 很大_为什么MySQL的data_free大于数据和索引的组合?

我假设您使用的是InnoDB,因为它是MySQL 5.5中的默认存储引擎.InnoDB表空间在插入数据时会增长,但删除数据时文件不会缩小.因此,例如,如果您插入100万行,然后删除它们,该文件将有很多物理分配的空间,但不再使用.如果可以再次增加表空间文件,InnoDB将重新使用该空间.此外,即使您不删除,也可能存在一些“浪费”的空间,因为当表空间文件的大小增加时,它们会被一大块页面扩展,这些页面由...

weixin_42596011的博客 3326

Skiplist,B,B+tree,LSM tree

SkipList 理解(如何实现): 即使是有序的链表,查找的时间复杂度也是O(n),但链表不能随机访问所以不适用于二分查找,使得查找的时间复杂度为O(logn)。 于是将有序链表和二分查找结合得到了SkipList,类似于二叉搜索树,这是一种以空间换时间的算法,通过在每个节点中增加向前的指针,从而提升查找效率(如下图所示)。 一开始如a所示,是一个有序的链表,时间复杂度O(n)。随后建立了e所示的SkipList,从最顶层往下查找,可以跳过许多元素,减少查找次数。 ​

weixin_45875458的博客 947

mysql 导入 csv 大文件怎么打开_mysql导入超大内存的csv文件

1.直接用命令2.用分割器分割,再用导入最后要commit,不然没有真的导入数据库中。其中出现的问题:The MySQL server is running with the --secure-file-priv option so it cannot execute this statement解决方法:【我的做法】【必须SQL文件和数据表都要在指定目录中】指定路径查询:show variabl...

weixin_42400518的博客 365

ECU-TEST笔记&使用技巧01

说明 1)所述均基于如下环境:ECU-TEST 8.0、Win10系统、NI Veristand 2018(HIL测试)。不排除因为版本及软件环境问题,所述方法不奏效或有更好的方法,欢迎交流,一起提高。 2)本博客以问答形式进行,所述问题均来自于实际测试(包括MIL、HIL测试)遇到的问题及需求,目的是提高测试效率和自动化测试序列的可维护性。 3)本博客尽量从测试方法及ECU-TEST原...

Eigrl的博客 1万+

【电脑技巧】CPU正常运行时间过长,怎么解决?

目录 问题描述 解决方案 1、问题描述 不少同志都遇到过这样的问题:按【Ctrl + alt + delete】打开任务管理器,切到“性能”选项卡下,发现自己电脑的CPU正常运行时间竟然为好几十天!很多人担心这会不会影响电脑的寿命?于是很想知道这是怎么回事,以及如何解决这个问题。 我在此解答一下,这是由于你的电脑开启了“快速启动”这一选项的缘故,只要把这一选项关闭,问题就解决了。 2、解决方案 怎样关闭“快速启动”呢?按照如下的步骤来即可。 顺便声明一下,笔者的电脑配置: 使用电脑:联想Yoga 14

橄榄树下的孩子 3万+

MySQL批量导入数据表空间膨胀的一问题场景

看到叶老师写的这篇文章《MySQL批量导入数据时,为何表空间膨胀了N倍》,针对数据导入问题的排查思路,值得我们借鉴,学习一下。如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,近期更新的文章:《MySQL中的单引号和双引号》《介绍一个MySQL参数检索工具》《如何通过连接判断应用访问数据库的异常行为场景?》《共饮新年的第一口鸡汤》《MySQL的caching...

bisal的专栏 452

YOLOv11改进 | 上采样篇 | YOLOv11引入CARAFE上采样

在本文中,我们提出了一个通用、轻量级、高效的特征重组算子CARAFE来实现这一目标.CARAFE有几个吸引人的特性:(1)大视场。(2)内容感知处理。到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~大视场:不同于以往的方法(如双线性插值),CARAFE能够在更大的感受野内聚合上下文信息,从而捕获更丰富的语义信息。

tsg6698的博客 921

mysql 表空间收缩_Greenplum 列存表(AO表)的膨胀和垃圾检查与空间收缩

Greenplum释放表的空间1 Greenplum产生垃圾空间说明Greenplum支持行储存(HEAP储存)与列(append-only)储存,对于AO存储,虽然是appendonly,但实际上GP是支持DELETE和UPDATE的,被删除或更新的行,通过BITMAP来标记删除与修改。AO存储是块级组织,当一个块内的数据大部分都被删除或更新掉时,扫描它浪费的成本实际上是很高的。而Postgre...

weixin_30647489的博客 600

【数字孪生与仿真技术】06:航天器系统建模与验证全流程实战:从多学科建模到数字孪生(附完整代码与工业案例)

摘要:航天器系统开发面临多学科耦合强、验证流程复杂、可靠性要求极高的挑战。本文基于MATLAB/Simulink平台,系统阐述航天器从多域建模、动力系统开发到任务验证的全流程技术框架。内容涵盖Modelica统一建模规范、光伏-电池联合供电系统仿真、基于模型的需求追溯方法、蒙特卡洛可靠性分析及硬件在环测试等核心技术,并结合James Webb太空望远镜电力系统案例,展示工业级应用实践。文中提供完整的Simulink模型代码、仿真结果及流程图,最后探讨数字孪生与AI增强技术在航天器在轨运维中的未来应用。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1373

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

MySQL数据导入Doris后存储空间占用减少的原因分析

Doris对不同的数据类型提供了不同的编码方式,例如INT类型数据使用BitShuffle编码,字符串类型数据使用字典编码,而且Doris还会根据列的值的分布情况自动切换编码类型,以避免不必要的空间浪费。这会增加表空间的膨胀率。例如,使用DataX或X2Doris等工具进行数据迁移时,由于它们的并行处理和优化算法,可能会更有效地减少数据膨胀和存储空间的使用。:Doris采用了聚合模型,这意味着在插入数据时,相同的键值会被聚合,只保留聚合后的键值,从而减少了数据的冗余和存储空间的使用。类型的N表示字节长度。

学亮编程手记 990

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

SpringBoot+ThreadPoolTaskExecutor 批量插入百万级数据实测

本文针对百万级数据批量插入的性能优化提出完整解决方案。通过分析单线程插入的三大瓶颈(IO阻塞、事务开销、连接耗尽),提出多线程+批量插入的优化策略。关键点包括:1)开启JDBC的rewriteBatchedStatements参数实现真正批量;2)使用ThreadPoolTaskExecutor进行任务并行处理;3)合理配置线程池参数(核心线程数建议CPU核数*2)。实测显示,20线程处理200万数据仅需43秒,较单线程提升7.3倍。文章还提供了完整代码实现,并深入探讨了生产环境中的OOM防护、事务补偿、线

油墨香^-^的博客 1063

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

遇到InnoDB的共享表空间文件ibdata1文件大小暴增时,应该如何处理?

1、问题背景 用MySQL/InnoDB的童鞋可能也会有过烦恼,不知道为什么原因,ibdata1文件莫名其妙的增大,不知道该如何让它缩回去,就跟30岁之后男人的肚腩一样,汗啊,可喜可贺的是我的肚腩还没长出来,hoho~ 正式开始之前,我们要先知道ibdata1文件是干什么用的。 ibdata1文件是InnoDB存储引擎的共享表空间文件,该文件中主要存储着下面这些数据: data dict...

u013568834的专栏 807

mysql ibdata_MySQL问答系列之如何避免ibdata1文件大小暴涨

0、导读ibdata1文件是什么?ibdata1是一个用来构建innodb系统表空间的文件,这个文件包含了innodb表的元数据、撤销记录、修改buffer和双写buffer。如果file-per-table选项打开的话,该文件则不一定包含所有表的数据。当innodb_file_per_table选项打开的话,新创建表的数据和索引则不会存在系统表空间中,而是存放在各自表的.ibd文件中.显然这个文...

weixin_39890629的博客 189

关于那些mysql的数据读写和日志机制

MySQL的底层原理涉及数据读写与日志机制,主要关注InnoDB存储引擎。其核心组件包括缓冲池、日志系统和事务系统,共同确保数据的一致性和持久性。日志机制主要包括RedoLog、UndoLog和Binlog。RedoLog用于崩溃恢复,记录数据页的物理修改;UndoLog用于事务回滚和多版本并发控制,记录事务前的数据状态;Binlog用于主从复制和恢复,记录修改数据的SQL语句。MySQL采用两阶段提交机制确保RedoLog和Binlog的一致性。优化建议包括调整日志文件大小、选择适当的日志格式和监控长事务

Francoder_的博客 1407

mysql基本数据长度_MySQL的类型与数据长度

之前遇到一个问题“怎么评估一行MySQL记录占据了多少字节?”。自己当时也不是特别清楚。当时只是简单的知道,具体的长度跟编码相关。前几天系统研究了一下MySQL中的编码问题,铺垫已经做好,那就研究下长度的问题。1 类型及长度1.1 charchar 最长255个字符(自从了解了MySQL的字符编码,每次写字符还是字节,都得考虑3秒)看报错信息:1.2 varchar1.2.1 varchar的最大...

weixin_36018748的博客 3840

MySQL 5.7 安全甩掉 undo001 生产笔记

摘要: MySQL 5.7实例运行3年后undo001膨胀至380GB,通过调整参数innodb_undo_tablespaces=3并两次重启实现安全回收。首次重启新建undo002/003,标记旧文件inactive;清除长事务后等待purge线程清空,二次重启自动删除空文件。全程需kill空闲长事务(脚本可自动化),确保零数据丢失,仅分钟级中断。适用于5.7版本undo空间回收,注意从库需同步操作。生产验证有效,回收380GB空间。

qq_29678597的博客 343

FAQ系列 | 如何避免ibdata1文件大小暴涨

​遇到InnoDB的共享表空间文件ibdata1文件尺寸暴增时,应该如何处理?

老叶茶馆 461

mysql数据库ibdata1文件瘦身

遇到InnoDB的共享表空间文件ibdata1文件大小暴增时,应该如何处理? 1、问题背景 用MySQL/InnoDB的童鞋可能也会有过烦恼,不知道为什么原因,ibdata1文件莫名其妙的增大,不知道该如何让它缩回去,就跟30岁之后男人的肚腩一样,汗啊,可喜可贺的是我的肚腩还没长出来,hoho~ 正式开始之前,我们要先知道ibdata1文件是干什么用的。 ibdata1

没事就写点 978

MySQL底层:InnoDB引擎里到底是什么?

调优:知道 Buffer Pool 的重要性,你就会合理设置。排错:理解 Redo Log 和 Checkpoint 机制,就能分析为何磁盘 I/O 飙升。设计:明白聚簇索引和回表的代价,就会在设计表结构时慎重选择主键。并发:掌握 MVCC 和锁机制,就能写出避免死锁、减少等待的高效 SQL。InnoDB 是一个复杂而精妙的系统,它的每一个功能区都在为“高性能、高可靠、高并发”的目标服务。

河阿里的博客 561
上一篇: 图文结合带你搞懂MySQL日志之Slow Query Log(慢查询日志)
下一篇: 一文简单了解并部署Zookeeper集群
GreatSQL社区
博客等级 码龄5年 1210粉丝 390原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值