技术分享 | MySQL 的几种数据迁移方案

1需求背景

应用侧的同学需要对数据进行导出和导入,于是跑来找 DBA 咨询问题:MySQL 如何导入大批量的数据?

应用侧目前的方式:

  • mysqldump 工具

  • select outfile 语句

  • 图形化管理工具(MySQL Workbench、Navicat 、DBeaver)

DBA 听了觉得挺好的呀!

DBA 想了,我的数据库我做主。通知应用侧,目前先使用之前熟悉的方式进行,测试之后给建议。

Tips:为了防止导入时出现大事务,造成主从延迟。

2方案准备

待测方案:mysqldump、mydumper、select outfile 语句、Util.dumpTables 、Util.exportTable

环境配置信息

配置项说明
MySQL 版本5.7.39
磁盘随机读写100 MiB/sec
测试表名test.t_order_info
行数1000W
字段数6

建表语句

CREATE TABLE `t_order_info` (`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',`order_no` varchar(64) NOT NULL DEFAULT '0000' COMMENT '订单编号',`order_status` varchar(2) NOT NULL DEFAULT '01' COMMENT '订单状态: 00-异常、01-待处理、02-进行中、03-已完成',`flag` tinyint(4) NOT NULL DEFAULT '1' COMMENT '删除标识: 1-正常、0-逻辑删除',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`ID`),UNIQUE KEY `IDX_ORDER_NO` (`order_no`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='订单表'

导出文件

  • 包含数据结构和数据的 备份文件 (mysqldump、mydumper、Util.dumpTables)

  • 只包含数据的 数据文件 (select outfile、Util.exportTable)

导出导入命令

导出导入
mysqldumpsource 或 mysql< xxx.sql
mydumpermyloader
select outfileload data
Util.dumpTablesUtil.loadDump
Util.exportTableUtil.importTable

3方案测试

测试首先考虑的是 提升导入效率,并新增了 MySQL Shell 的使用。

mysqldump

单表导出(备份文件)

mysqldump --default-character-set=utf8mb4 --master-data=2 --single-transaction --set-gtid-purged=off --hex-blob  --tables test t_order_info
  • --master-data=2 参数会在备份期间对所有表加锁 FLUSH TABLES WITH READ LOCK,并执行 SHOW MASTER STATUS 语句以获取二进制日志信息。因此,在备份期间可能会影响数据库的并发性能。如果您不需要进行主从复制,则可以考虑不使用 --master-data=2 参数。

  • --single-transaction 参数用于在备份期间“使用事务来确保数据一致性”,从而避免在备份期间锁定表。[必须有]

备份文件

文件内容。

-- Table stricture for table `t_order_info`
--DROP TABLE IF EXISTS `t_order_info`;
/*!40101 SET @saved_cs_client= @@character_set_client */;
/*!49101 SET character_set_client = utf8 */;
CREATE TABLE `t_order_info` (`ID` bigint(2) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',`order_no` varchar(64) NOT NULL DEFAULT `0000` COMMENT '订单编号',`order_status` varchar(2) NOT NULL DEFAULT '01' COMMENT '订单状态: 80-异常、81-待处理、2-进行中、03-已完成',`flag` tinyint(4) NOT NULL DEFAULT '1' COMMENT '删除标识: 1-正常、0-逻辑删除',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`ID`),UNIOUE KEY `IDX_ORDER_NO` (`order no`)
) ENGINE=InnODB AUTO_INCREMENT=10129913 DEFAULT CHARSET=utf8m COMMENT='订单表';
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `t_order_info`
--LOCK TABLES `t_order_info` WRITE;
/*!40000 ALTER TABLE `t_order_info` DISABLE KEYS */;

文件内容解释:

  • 没有建库语句,因为是单表备份。

  • 有删除表,建立表的语句,小心导入目标库时,删除表的语句,造成数据误删。

  • INSERT 语句没有字段名称,导入时表结构要一致。

  • 导入过程中有 lock table write 操作,导入过程中相关表不可写。

  • ALTER TABLE t_order_info DISABLE KEYS 此语句将禁用该表的所有非唯一索引,这可以提高插入大量数据时的性能。 对应的文件末尾有 ALTER TABLE t_order_info ENABLE KEYS;

用途,可以将备份文件中的数据导入自定义库,“文件内容解释”部分遇到的问题可以使用下面参数解决。

  • --no-create-info 不包含建表语句(可以手动创建 create table tablename like dbname.tablename;

  • --skip-add-drop-database 不包含删库语句

  • --skip-add-drop-table 不包含删表语句

  • --skip-add-locks INSERT 语句前不包含 LOCK TABLES t_order_info WRITE;

  • --complete-insert INSERT 语句中包含 列名称(新表的列有增加的时候)。

单表导出备份数据(只导出数据)。

mysqldump --default-character-set=utf8mb4 --master-data=2 --single-transaction --set-gtid-purged=off --hex-blob --no-create-info --skip-add-drop-table --skip-add-locks --tables dbname tablename// 部分数据导出追加参数
--where="create_time>'2023-01-02'"

导出单库中的某表为 CSV。

// 可选不导出表结构,
--no-create-info --skip-add-drop-database --skip-add-drop-table
/data/mysql/3306/base/bin/mysqldump -uadmin -p123456 -P3306 -h127.0.0.1 --default-character-set=utf8mb4 --single-transaction --set-gtid-purged=OFF  --triggers --routines --events --hex-blob --fields-terminated-by=',' --fields-enclosed-by='"' --lines-terminated-by='\n'  -T /data/mysql/3306/tmp test//其中 test 后面也可以指定表名,不指定就是全库。
test t_order_info t_order_info01
其中 --single-transaction --set-gtid-purged=OFF  --triggers --routines --events --hex-blob 
为了防止提示,可选

小结

1G 的备份文件,测试结果如下:

  1. 使用 mysql< xxx.sql 导入,耗时 5 分钟。

  2. 使用用 source xxx.sql 导入, 耗时 10 分钟。

推荐第一种,都是单线程。

mydumper

  • 版本 0.14.4

多线程导出

mydumper -u admin -p 123456 -P 3306 -h 127.0.0.1 -t 8 --trx-consistency-only -G -E -R --skip-tz-utc --verbose=3 --compress --no-schemas --rows=1000000  -T test.t_order_info  -o /backup// 导出时支持部分导出追加参数--where="create_time>'2023-01-02'"// 文件输出
test01.t_order_info.00000.dat # 包含 CSV 数据
test01.t_order_info.00000.sql # 包含 LOAD DATA 语句// 导入命令
LOAD DATA LOCAL INFILE '/data/mysql/3306/tmp/test01.t_order_info.00005.dat' REPLACE INTO TABLE `t_order_info` CHARACTER SET binary FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '\\' LINES STARTING BY '' TERMINATED BY '\n' (`ID`,`order_no`,`order_status`,`flag`,`create_time`,`modify_time`);
  • 多线程导入

myloader -u admin -p 123456 -P 3306 -h 127.0.0.1 --enable-binlog -t 8 --verbose=3 -B test -d /backup//  导入主库时需要添加 
--enable-binlog// 库名可以自定义
-B test 

小结

耗时 2 分钟,建议如下:

  • 在数据量大于 50G 的场景中,更推荐 mydumper。

  • 补充场景,支持导出 CSV,也支持 --where 过滤。

mydumper -u admin -p 123456 -P 3306 -h 127.0.0.1 -t 8 --trx-consistency-only -G -E -R --skip-tz-utc --verbose=3 --where="create_time>'2023-01-02'" --no-schemas --rows=1000000 --load-data --fields-terminated-by ',' --fields-enclosed-by '"' --lines-terminated-by '\n' -T test.t_order_info  -o /backup

导入命令同上,且可以按需手动进行 LOAD DATA

SELECT OUTFILE 语句

Tips:适合于单表数据的导出,不支持多表。

导出命令,耗时 15 秒。

SELECT * from test01.t_order_info INTO OUTFILE "/data/mysql/3306/tmp/t_order_info0630_full.csv" CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\'' LINES TERMINATED BY '\n';//  带列名导出,导入时需添加 IGNORE 1 LINES;
SELECT *  INTO OUTFILE "/data/mysql/3306/tmp/t_order_info0630_full.csv" CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\'' LINES TERMINATED BY '\n'  from (select 'id','order_no','order_status','flag','create_time','modify_time' union all select * from test01.t_order_info) b;

导入命令,耗时 3 分钟。

mysql -uadmin -P3306  -h127.0.0.1 -p123456  --local-infile
load data local infile '/data/mysql/3306/tmp/t_order_info0630_full.csv'  into table test.t_order_info CHARACTER SET utf8mb4 fields terminated by ',' OPTIONALLY ENCLOSED BY '\'' lines terminated by '\n';

小结

  • 支持跨表导入。A 表的数据可以导入 B 表,因为备份文件中只有数据。

  • 可自定义导出部分列,导出导入速度较快,最常用。

MySQL_Shell > dumpTables

单表导出,耗时 4 秒。

util.dumpTables("test", ["t_order_info"], "/backup") 

部分导出。

util.dumpTables("test", ["t_order_info"], "/backup", {"where" : {"test.t_order_info": "create_time>'2023-01-02'"}})

导入,耗时 3 分钟。

util.loadDump("/backup") 

注意:不支持部分导入,不支持跨数据库版本。

因为导入时最大支持 2 个参数,可以将导出的部分数据全部导入到新的库中。

导入命令:util.loadDump("/backup",{schema: "test_new"})

小结

  • 支持跨库导入,A 库的数据可以导入 B 库。表名需要一致。不支持增量到已有数据的表中。

  • 导出时和 SELECT OUTFILE 同效,导入时,比 LOAD DATA 快(默认 4 线程)。

注意:

  1. 部分导出功能需要较新的 MySQL Shell 版本,如 8.0.33。

  2. LOAD DATA 单线程导入 耗时 1h20min。

MySQL_Shell > exportTable

单表导出,耗时 10 秒。

util.exportTable("test.t_order_info",   "/backup/t_order_info.csv", {defaultCharacterSet: "utf8mb4", fieldsOptionallyEnclosed: true, fieldsTerminatedBy: ",", linesTerminatedBy: "\n", fieldsEnclosedBy: '"', defaultCharacterSet: "utf8mb4", showProgress: true, dialect: "csv"}) 

部分导出。

util.exportTable("test.t_order_info",   "/backup/t_order_info.csv",   {     dialect: "csv",     defaultCharacterSet: "utf8mb4",     fieldsOptionallyEnclosed: true,     fieldsTerminatedBy: ",",     linesTerminatedBy: "\n",     fieldsEnclosedBy: '"',     showProgress: true,     where: "create_time>'2023-01-02'" } )

导入,耗时 10 分钟。

util.importTable("/backup/t_order_info.csv", { "characterSet": "utf8mb4",     "dialect": "csv",     "fieldsEnclosedBy": "\"",     "fieldsOptionallyEnclosed": true,     "fieldsTerminatedBy": ",",     "linesTerminatedBy": "\n",     "schema": "test",     "table": "t_order_info" }) 

部分导入(不推荐使用)。

util.importTable("/backup/t_order_info.csv", {     "characterSet": "utf8mb4",     "dialect": "csv",     "fieldsEnclosedBy": "\"",     "fieldsOptionallyEnclosed": true,     "fieldsTerminatedBy": ",",     "linesTerminatedBy": "\n",     "schema": "test100",     "table": "t_order_info" })util.importTable("/backup/t_order_info0630.csv", {      "characterSet": "utf8mb4",     "dialect": "csv",     "fieldsEnclosedBy": "\"",     "fieldsOptionallyEnclosed": true,     "fieldsTerminatedBy": ",",     "linesTerminatedBy": "\n",     "schema": "test",     "table": "t_order_info" }) 

有报错 MySQL Error 1205 (HY000): Lock wait timeout exceeded; try restarting transaction @ file bytes range [450000493, 500000518) 需要重复执行一次,才能保证数据完整。

根据报错提示可以使用以下命令导入:

LOAD DATA LOCAL INFILE '/backup/t_order_info0630.csv' INTO TABLE `test`.`t_order_info` CHARACTER SET 'utf8mb4' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\\' LINES STARTING BY '' TERMINATED BY '\n';

MySQL 5.7 也推荐直接使用 LOAD DATA

小结

  • 支持跨库导入,A 库的数据可以导入 B 库,表名需要一致。

  • 导出时和 SELECT OUTFILE 同效。导入时,比 LOAD DATA 快(默认 8 线程)。

4总结

可以通过数据大小进行选用:

导出导入优点推荐度(效率)
mysqldumpsource xxx.sql
MySQL< xxx.sql
原生,可远程⭐⭐⭐
数据量<10G
mydumpermyloader多线程⭐⭐⭐
数据量>50G
SELECT OUTFILELOAD  DATA最灵活⭐⭐
数据量<20G
Util.dumpTablesUtil.loadDump原生,多线程⭐⭐⭐
数据量<50G
Util.exportTableUtil.importTable原生,单线程
数据量<20G
  • MySQL< 导入时,需要避免数据丢失。

  • 前 3 种都支持 WHERE 过滤,mydumper 是最快的。SELECT OUTFILE 最常用(因为支持自定义导出部分列)。

  • 前 2 种因为是备份工具,所以有 FTWRL 锁。

  • Util.dumpTables 不支持增量到已有数据的表中,因为包含了库表的元数据信息,像 mydumper。

  • Util.exportTable 备份是单线程,导入是多线程,不推荐的原因是导入容易出错(多次导入可解决)。

  • 使用建议:按照数据量选择,全表备份最快用 Util.dumpTables,部分备份用 SELECT OUTFILE

  • 测试之后再使用,导出和导入均需要进行数据验证。

文章来源于爱可生开源社区 ,作者陈伟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/671090.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言初阶-结构体】关于结构体的声明定义、结构体传参详解

目录 1. 结构体的声明 1.1 结构的基础知识 1.2 结构的声明 1.3 结构成员的类型 1.4 结构体变量的定义和初始化 2. 结构体成员的访问 2.1(.)操作符 2.2&#xff08;->&#xff09;操作符 3.结构体传参 1. 结构体的声明 1.1 结构的基础知识 结构体是一些值的集合&…

uniapp vue3怎么调用uni-popup组件的this.$refs.message.open() ?

vue2代码 <!-- 提示信息弹窗 --><uni-popup ref"message" type"message"><uni-popup-message :type"msgType" :message"messageText" :duration"2000"></uni-popup-message></uni-popup>typ…

算法笔记刷题日记——3.简单入门模拟 3.2 查找元素

刷题日记 3.2 查找元素 B1041 B1004 B1028 B1032 A1011 A1006 A1036 错题记录 B1028 人口普查 某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的&#xff0c;但不一定是合理的…

你为什么不喜欢关电脑?我只是想第二天能够快速进入工作状态

程序员不喜欢关电脑的主要原因就是&#xff1a;想第二天能够快速进入工作状态。大部分不喜欢关电脑的程序员都是很敬业的程序员。 程序员的电脑上安装了很多软件&#xff0c;包括IDE、数据库客户端、Redis客户端、思维导图、画图工具、数据库设计工具等。通常在工作的时候也会…

开关电源学习之Boost电路

如果我们需要给一个输入电压为5V的芯片供电&#xff0c;而我们只有一个3.3V的电源&#xff0c;那怎么办&#xff1f; 我们能不能把3.3V的电压升到5V&#xff1f; 一、电感的简介 而在升压的电路设计方案中&#xff0c;使用到一个重要的元器件&#xff1a;电感。 电感的特性…

【PyQt】05-多线程

文章目录 前言一、什么是单线程、多线程二、代码现象示例多线程代码运行结果 总结 前言 文章开始还是解释一下&#xff0c;这是跟着王铭东老师学习的。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、什么是单线程、多线程 单线程 在Python中&am…

TCP和UDP相关问题(重点)(1)

1.TCP与UDP的区别&#xff1f; TCP和UDP都是传输层的协议&#xff0c;对于TCP来说在传输数据前是必须要建立连接的&#xff0c;而UDP在传输数据前不需要建立连接&#xff1b;TCP是可靠传输服务&#xff0c;有三次握手、数据的确认、重传等机制&#xff0c;而UDP是不可靠的&…

PDF文件格式(一):交叉引用流

在PDF-1.5版本之前&#xff0c;对象的交叉引用信息是存储在交叉引用表(cross-reference table)中的。在PDF-1.5版本之后&#xff0c;引进了交叉引用流(cross-reference stream)对象&#xff0c;可以用它来存储对象的交叉引用信息&#xff0c;就像交叉引用表的功能一样。 采用交…

C遗漏知识(个人向)

之前C语言遗漏的一些。 数据在内存中的存储 原码、反码、补码 整数的2进制表⽰⽅法有三种&#xff0c;即 原码、反码和补码 正整数的原、反、补码都相同。 负整数的三种表⽰⽅法各不相同。 原码&#xff1a;直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。 反码&…

力扣383-赎金信

赎金信 题目链接 解题思路 统计magazine中字符出现的字符&#xff0c;用哈希表保存遍历ransomNote&#xff0c;记录其中出现的字符&#xff0c;出现一次&#xff0c;哈希表删除对应的字符遍历哈希表&#xff0c;如果有的字符出现的次数为负数&#xff0c;则不能拼凑出目标字符…

Javascript入门学(基础)

软件篇 JS基础语法第一天 1.javascript介绍 1.1 js是什么 是什么 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互效果&#xff0c;而html和css是标记性语言&#xff0c;并非编程语言有什么用 js的组成 htmlcssjs实现按钮点击功能 …

Vision Transfomer系列第一节---从0到1的源码实现

本专栏主要是深度学习/自动驾驶相关的源码实现,获取全套代码请参考 这里写目录标题 准备逐步源码实现数据集读取VIt模型搭建hand类别和位置编码类别编码位置编码 blocksheadVIT整体 Runner(参考mmlab)可视化 总结 准备 本博客完成Vision Transfomer(VIT)模型的搭建和flowers数…

什么是大模型

目录 让你了解什么是大模型什么是大模型&#xff1f;大模型的应用场景常见的大模型技术实例分析&#xff1a;深度学习语言模型GPT-3 让你了解什么是大模型 大模型&#xff08;Big Model&#xff09;是指在机器学习和人工智能领域中处理大规模数据和复杂模型的一种方法或技术。…

股票K线简介

股票K线&#xff08;K-Line&#xff09;是用于表示股票价格走势的图形&#xff0c;主要由四个关键价格点组成&#xff1a;开盘价、收盘价、最高价和最低价。K线图广泛应用于股票市场技术分析中&#xff0c;它提供了丰富的信息&#xff0c;帮助分析师和投资者理解市场的行情走势…

一周学会Django5 Python Web开发-Django5介绍及安装

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计10条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

leetcode 74.搜索二维矩阵

本题其实就是一个变形的二分查找而已。这里不采用两次二分或者一次二分的方法了&#xff0c;leetcode上是很详细的&#xff0c;这里就讲讲普通的思路是怎样的。 思路&#xff1a;首先就是把二维数组化为一维数组&#xff0c;这个时候一维数组需要开的大一些&#xff0c;不然的…

算法练习-四数之和(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;数组 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨在…

“过年买年货,花光了我的年终奖”

【潮汐商业评论/原创】 前脚刚进家门&#xff0c;后脚快递电话一个接着一个。 临近春节&#xff0c;Julia是提前批回家的年轻人&#xff0c;与Julia一同到家的还有她的年货。上至大小家电&#xff0c;下到坚果零食&#xff0c;短短几天快递就堆满了客厅。 吃的喝的还能理解&…

Linux 【yum 和 rpm 的区别】

结论 rpm和yum都是在Red Hat系列的Linux发行版&#xff08;如Fedora、CentOS、RHEL等&#xff09;中用于管理软件包的工具&#xff0c;但它们的使用场景和功能有所不同。 rpm&#xff08;Red Hat Package Manager&#xff09;是一个较低级别的工具&#xff0c;它直接处理.rpm文…

MySQL的优化

优化MySQL的几点&#xff1a; 从设计上优化 从查询上优化 从索引上优化 从存储上优化 1&#xff0c;SQL的执行频率 MySQL客户端连接成功后&#xff0c;通过show [session/global] status命令可以查看服务器状态信息。通过查看状态信息可以查看对当前数据库的主要操作类型…