source命令导入超大SQL文件易卡住或失败,因其逐行解析执行、默认autocommit导致频繁I/O与日志压力;需前置执行SET sql_log_bin=OFF、SET autocommit=0、SET unique_checks=0和SET foreign_key_checks=0,并在导入后恢复检查并COMMIT;更高效方式是用mysql命令行重定向直接喂入SQL流。

source 命令在导入超大 SQL 文件时为什么卡住或失败
因为 source 是 MySQL 客户端内置命令,它逐行读取、解析并执行 SQL 语句,不走网络协议层,也不受 max_allowed_packet 等服务端限制——但恰恰因此,它无法跳过语法错误、无法跳过重复插入冲突、无法控制事务粒度,且默认启用 autocommit。一个 1GB 的文件里若有上万条 INSERT,每条都自动提交,I/O 和日志写入压力会直接拖垮导入速度,甚至触发超时中断或内存溢出。
用 source 导入前必须调优的三个关键参数
进入 MySQL 客户端后,在 USE database_name; 之后、source 之前,务必执行:
-
SET sql_log_bin = OFF;—— 关闭二进制日志,避免主从同步压力和磁盘写放大(仅限从库或单机开发环境) -
SET autocommit = 0;—— 禁用自动提交,让后续所有语句包裹在隐式事务中 -
SET unique_checks = 0;和SET foreign_key_checks = 0;—— 暂停唯一索引校验与外键约束检查,导入后再恢复(否则每条 INSERT 都要查索引)
执行完 source /path/to/big.sql 后,别忘了补上:
SET unique_checks = 1;SET foreign_key_checks = 1;COMMIT;
真正适合超大文件的导入方式:mysql 命令行重定向
比 source 更底层、更高效的方式是绕过客户端解析,直接把 SQL 流喂给 MySQL 服务进程:
mysql -u root -p -D database_name --default-character-set=utf8mb4
这种方式的优势在于:
- 不经过 MySQL 客户端的 SQL 解析器,无额外内存开销
- 支持服务端级的
max_allowed_packet控制(需提前在 my.cnf 中设为 512M 或更高) - 可配合
pv(Linux)或gtime(macOS)监控进度:pv big.sql | mysql -u root -p -D db - Windows 下可用
type big.sql | mysql -u root -p -D db
注意: 重定向方式无法跳过文件中的错误语句——一旦某条 SQL 报错,整个导入终止;而 <code>source 至少能报错后继续(取决于错误类型)。
容易被忽略的字符集与路径陷阱
即使参数全对,这两点仍会让导入静默失败或乱码:
- SQL 文件本身编码不是 UTF-8(比如是 GBK 或 Latin1),但没加
--default-character-set=utf8mb4,会导致中文变 ? 或截断 - 路径含空格或中文时,
source不支持引号,source "D:\my data\dump.sql"会报错;必须用正斜杠且无空格:source D:/my_data/dump.sql - Linux/macOS 下路径区分大小写,
source /tmp/DUMP.SQL找不到dump.sql
最稳妥的做法:把 SQL 文件放到 /tmp/(Linux/macOS)或 MySQL bin/ 目录下(Windows),用短路径 + 小写文件名,再配合显式字符集参数启动导入。


















