应改用 mysql -u user -p db_name
source 命令卡住或报错:MySQL 客户端不支持超大文件直接执行
MySQL 客户端的
source命令本质是逐行读取、解析并执行 SQL,遇到几 GB 的文件时,它会把整个文件加载进内存缓冲区(尤其在旧版本中),极易触发ERROR 2013 (HY000): Lost connection to MySQL server during query或直接卡死无响应。这不是你网络或权限的问题,而是客户端设计限制 —— 它不是为批量导入设计的工具。
- 别用
mysql -u root -p -e "source /path/to/big.sql"这种写法,source只能在交互式客户端里用,命令行 -e 模式根本不识别它- 别在 MySQL Shell(mysqlsh)里用
source,它和传统 mysql 客户端行为不一致,容易报Unknown command 'source'- 如果文件含
CREATE DATABASE或USE,确保目标库已存在且用户有权限;否则执行中途失败,但source不会自动回滚前面已执行的部分真正该用的命令:mysql 命令行直连 + 文件重定向
绕过客户端解析层,让 MySQL 服务端直接处理流式输入,这才是导入大文件的正解。核心就是不用
source,改用 shell 级重定向:mysql -u root -p database_name <p>这个操作跳过了 mysql 客户端的 SQL 解析逻辑,SQL 内容以原始字节流发给服务端,效率高、内存占用低、稳定性强。</p>
- 必须指定数据库名(
database_name),否则遇到INSERT INTO table...会报ERROR 1046 (3D000): No database selected- 如果 SQL 文件开头有
CREATE DATABASE和USE,先手动建库再执行,或者拆成两步:mysql -u root -p- 导入过程中看不到进度,加
--verbose也没用;如需监控,可用pv /path/to/big.sql | mysql -u root -p target_db(需提前装pv)关键参数调优:避免 “Packet too large” 和超时中断
即使用了重定向,超大 SQL 文件仍可能触发服务端限制,最常见的是
ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes,或连接被wait_timeout中断。必须在执行前临时调高这两个值(仅对当前会话生效):
mysql -u root -p -e "SET GLOBAL max_allowed_packet = 1073741824; SET GLOBAL wait_timeout = 28800;"然后再执行导入。注意:
max_allowed_packet单位是字节,1G =1073741824;设太大可能被系统内存限制拒绝,建议从 512M 起步尝试SET GLOBAL需要 SUPER 权限;若无权限,只能改配置文件my.cnf并重启 MySQL,但生产环境重启代价高,优先走会话级设置wait_timeout默认通常 28800 秒(8 小时),足够大多数场景;若文件极大,可设为0(表示禁用超时),但不推荐长期使用导入后验证:别只看“没报错”,要看数据是否完整
大文件导入常出现静默截断:比如某条 INSERT 因字段长度超限被跳过,但后续语句继续执行,最终表行数比预期少几千甚至几万,却没有任何错误提示。
务必做三件事:
- 检查 MySQL 错误日志(路径通常是
/var/log/mysql/error.log或mysqld --help --verbose | grep "log-error"),搜索Warning和Truncated- 对比源 SQL 中的
INSERT语句数量(可用grep -c "^INSERT" big.sql)和目标表COUNT(*),注意有些 INSERT 是多值形式,一行含多个记录- 抽样查几条明显的数据(比如 ID 最大/最小的记录、带时间戳的最新记录),确认字段内容没被截断或乱码,尤其是 TEXT/BLOB 类型
真正麻烦的从来不是“怎么导进去”,而是“导进去的到底对不对”。很多线上事故,都是因为跳过了这一步。












