应使用 shell 重定向命令 mysql -u user -p db_name
别用
source导入 1G+ SQL 文件直接在 MySQL 客户端里执行
source命令导入 1G 以上文件,大概率会卡住、静默退出或报ERROR 2013 (HY000): Lost connection to MySQL server during query。这不是网络问题,是客户端设计限制:source会逐行读取、解析、拼接再发送,中间缓存膨胀,旧版本甚至把整个文件加载进内存。它不是为批量导入设计的 —— 就算你调高了max_allowed_packet,也拦不住解析层本身的瓶颈。真正该用的命令:
mysql -u user -p db_name这条 shell 级重定向命令绕过客户端 SQL 解析,让服务端直接流式接收原始字节,内存占用低、无中间缓冲、稳定性强。必须注意:
db_name必须显式指定,否则遇到INSERT INTO table会立刻报ERROR 1046 (3D000): No database selected- 如果 SQL 文件开头含
CREATE DATABASE或USE,先手动建库并确认用户有权限,或拆成两步:mysql -u root -p- 想看进度?装
pv:pv /path/to/big.sql | mysql -u root -p target_db(pv不是 MySQL 自带,需apt install pv或brew install pv)关键参数必须提前设,否则仍会中断
即使用了重定向,服务端仍可能因包大小或超时拒绝接收。这些参数只对当前连接生效,无需改配置文件、不用重启 MySQL:
- 加
--max_allowed_packet=1G防ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes- 加
--net_read_timeout=3600 --net_write_timeout=3600防连接被 wait_timeout 中断- 完整命令示例:
mysql -u root -p --max_allowed_packet=1G --net_read_timeout=3600 --net_write_timeout=3600 target_db注意:不要用
set global max_allowed_packet = ...,那会影响所有连接,且对已建立连接无效;也不要依赖 my.cnf 里设了就万事大吉 —— 客户端启动时未显式传参,仍可能沿用默认值(比如 4MB)。脚本内容比命令更重要:避免单行单 INSERT、关外键、删索引
即使命令和参数都对了,脚本本身写法差,导入速度也会慢几倍。重点检查:
- 确认 INSERT 是多值格式:
INSERT INTO t VALUES (1,'a'),(2,'b'),(3,'c');,而不是每行一个INSERT INTO t VALUES (1,'a');—— 后者会让网络往返和解析开销翻 N 倍- 脚本开头加:
SET FOREIGN_KEY_CHECKS = 0;;结尾加:SET FOREIGN_KEY_CHECKS = 1;,否则外键校验拖慢插入- 如有大量数据,导入前手动
ALTER TABLE t DISABLE KEYS;,导入后再ENABLE KEYS;(仅 MyISAM 有效;InnoDB 推荐删非主键索引,导入完重建)- 避免脚本里混
SET autocommit = 0却没配COMMIT,会导致事务长期挂起、磁盘空间暴涨最易被忽略的是:脚本里若有
DROP TABLE IF EXISTS或CREATE TABLE,但权限不足或表名冲突,错误发生后重定向模式不会报错退出,而是继续执行后续语句 —— 可能导致后面所有INSERT全丢进不存在的表,无声失败。












