mysqldump 导入超时本质是单条命令执行超服务端 wait_timeout 或客户端时限,大文件还易因内存不足被中断;拆分目的非提速而是规避超时,按表分割最稳妥,须确保语句完整、编码 UTF-8,并导入前禁用 autocommit 和校验。
为什么 mysqldump 导出的 SQL 文件导入会超时
本质是单条 mysql 命令执行时间过长,触发了连接超时(wait_timeout 或 interactive_timeout),或客户端(如 mysql workbench、phpmyadmin)自身设定了执行时限。大文件还容易因内存不足导致解析失败,不是“卡住”,而是被主动中断。
拆分不是为了“更快”,而是让每段脚本在安全时间内完成,规避超时机制本身。
- 常见错误现象:
MySQL server has gone away、Lost connection to MySQL server during query、phpMyAdmin 显示 “Script timeout passed” - 真正瓶颈往往不在网络,而在服务端的超时配置和单次 SQL 解析/执行开销
- 按表拆比按行拆更稳妥——保证每个片段是语法完整、可独立执行的语句块(如
CREATE TABLE+ 对应的INSERT)
用 split 按行切 SQL 文件风险很高
split 是纯文本切割工具,对 SQL 无感知。直接按行切,极大概率把一条长 INSERT INTO ... VALUES (...) 拆成两半,导致后续导入报错 You have an error in your SQL syntax。
- 仅适用于:已确认所有语句都以分号结尾且**每行只含一条语句**(如 mysqldump 加了
--skip-extended-insert) - 否则必须用能识别 SQL 语句边界的工具,比如
sed或专用脚本 - 命令示例(慎用):
split -l 1000 big.sql part_—— 这只适合调试,生产环境不推荐
按表分割最可靠:用 awk 提取 CREATE + INSERT 块
mysqldump 输出中,每个表的结构和数据有明确起始标记(CREATE TABLE `xxx`)和结束位置(下一个 CREATE TABLE 或文件尾)。用 awk 按此逻辑切,能保语法完整。
实操建议:
- 先确认 dump 文件编码为 UTF-8,避免
awk读取乱码 - 核心匹配模式:
/^CREATE TABLE/ { close(out); out = $3 ".sql" } { print > out }(注意$3是表名,带反引号需清洗) - 更健壮的做法是用 Python 脚本:逐行读,遇到
CREATE TABLE就新开文件,直到下个CREATE TABLE或/*!40101 SET */结束块 - 导出后检查每个小文件末尾是否含
;,缺失则手动补上,否则 MySQL 会等待下一行继续解析
导入时别忘了关掉 autocommit 和唯一性检查
拆完只是第一步,导入阶段不调参数,依然可能慢或失败。
- 每个小文件导入前加:
SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0; - 导入完成后加:
COMMIT; SET unique_checks=1; SET foreign_key_checks=1; - 否则每条
INSERT都触发索引更新和外键校验,性能断崖式下降 - 命令行导入示例:
mysql -u root -p database_name ,不要用 <code>source在交互式客户端里跑,它默认开启 autocommit
真正麻烦的不是怎么切,而是切完要不要重置自增 ID、是否要处理存储过程/视图/事件——这些不会出现在表级拆分结果里,得单独导出,容易漏。










