MySQL导入中断后应拆分SQL文件为独立可重试片段:用split按行切分,sed添加事务控制,再循环导入,避免重复执行USE或SET语句导致状态异常。
MySQL 导入中断后,source 命令不支持断点续传
直接用 mysql -u user -p database 或在客户端里执行 <code>source large.sql,一旦中断就只能重来——mysql 官方命令行工具压根没内置断点续传机制。这不是配置问题,是设计如此。
常见错误现象:ERROR 2013 (HY000): Lost connection to MySQL server during query 或终端被 Ctrl+C 中断后,再 source 同一个文件,会报主键冲突、重复插入或表结构已存在等错误。
- 别指望加
--force或--init-command能跳过已执行部分 -
mysql客户端不会记录执行到哪一行,它只按文本流解析 SQL,没有“执行位置”概念 - 如果 SQL 文件含
CREATE DATABASE或DROP TABLE,重跑可能直接破坏已有数据
用 sed + 行号定位,手动跳过已执行内容
前提是你知道上次卡在哪条语句(比如从日志/终端最后一行看到停在第 8247 行),或者能通过数据库当前状态反推——比如某张表已导入 32 万行,对应 SQL 文件里大概在哪个 INSERT INTO ... VALUES (...) 块附近。
实操建议:
- 先用
wc -l large.sql看总行数,再用sed -n '8247,8250p' large.sql检查目标位置上下文,确认是否为完整语句(注意分号结尾、括号是否闭合) - 用
sed -n '8248,$p' large.sql > resumed.sql截出剩余部分(行号从 8248 开始,跳过已执行的) - 导入前务必检查
resumed.sql开头有没有孤立的USE database;或SET FOREIGN_KEY_CHECKS=0;——这些可能已在前半段执行过,重复执行会干扰状态
更稳的方式:拆成带编号的独立 SQL 文件 + mysql 循环导入
适用于下次再导大文件,也适合把现有单文件切分后补救。核心是让每段可独立执行、失败后容易定位和重试。
使用场景:你有权限改写导入流程,且原始 SQL 是纯数据插入(不含复杂逻辑或跨事务依赖)。
- 用
split -l 5000 -d large.sql chunk_拆成每 5000 行一个文件(数字按实际单条 INSERT 长度调整,避免切在一条语句中间) - 对每个
chunk_00、chunk_01文件,用sed -i '1s/^/SET autocommit=0;/; $s/$/COMMIT;/'加上事务控制(防止中途失败留脏数据) - 写个简单 shell 循环:
for f in chunk_*; do mysql -u user -p database - 失败时,
echo输出立刻告诉你卡在哪一个 chunk,删掉已成功导入的 chunk,重跑后续即可
真正支持断点的替代方案:用 mydumper / myloader
mydumper 导出的不是单个 SQL 文件,而是按表拆成多个 .sql + .csv,myloader 导入时自带进度追踪和失败重试能力,本质是靠文件粒度而非行粒度实现“断点”。
性能与兼容性影响:
- 比原生
mysql导入快 3–5 倍(多线程 + 协议优化),但要求 MySQL 5.6+ 且需额外安装 - 不兼容含存储过程、触发器、自定义函数的导出(默认跳过,需加
--triggers、--routines显式开启) - 如果原始 SQL 是用
mysqldump --single-transaction生成的,myloader可直接读其输出,但必须确保导出时用了--skip-triggers --skip-routines,否则加载会报错
最常被忽略的一点:所有这些方法都假设你的 SQL 文件是“幂等友好”的——即重复执行同一段不会导致数据错乱。如果里面混了 UPDATE table SET counter = counter + 1 或 INSERT IGNORE 以外的逻辑,断点续传本身就会引入业务风险。










