导入大SQL文件需调大max_allowed_packet、禁用外键/唯一性检查、关闭自动提交、禁用索引重建,并合理设置缓冲池;推荐使用mydumper/myloader替代原生命令。
mysql 命令行导入大 SQL 文件时卡住或报错
直接用 mysql 命令导入几百 mb 以上的 sql 文件,常遇到连接中断、超时、mysql server has gone away 或 packet too large 错误。这不是文件本身有问题,而是客户端默认配置太保守。
- 先在 MySQL 服务端调大
max_allowed_packet(比如设为512M),否则即使命令行执行也会被服务端拒绝 - 客户端也要加参数避免本地缓冲限制:
mysql --max-allowed-packet=512M -u root -p database_name - 别用
source命令在交互式 mysql 里导入大文件——它不支持分块、没进度反馈、容易断 - 如果 SQL 文件含
CREATE DATABASE或跨库语句,确保目标库已存在且用户有权限,否则会静默失败
SQL 文件里有 SET NAMES、USE、DELIMITER 等语句导致命令行执行出错
mysql 命令行客户端对某些 SQL 语法支持不如 phpMyAdmin 完整,尤其涉及字符集切换、多语句分隔符、存储过程定义时,容易解析失败。
- 用
sed -i 's/SET NAMES utf8mb4;//g'(Linux/macOS)或gsed(macOS 需先brew install gnu-sed)删掉开头的SET NAMES行,改由连接参数统一指定:mysql --default-character-set=utf8mb4 - 把文件开头的
USE `dbname`;删掉,改用命令行指定数据库名,避免因库不存在导致后续全错 - 含
DELIMITER $$的存储过程导出文件,必须用mysql -e "source /path/to/file.sql"方式执行,不能直接重定向;更稳妥的是先用mysql -D dbname -e "source /path/to/file.sql"
导入中途断了,怎么续传而不是重头来
大文件导入耗时长,网络波动或终端断开后重跑代价太高。MySQL 本身不支持断点续传,但可以靠预处理规避。
- 用
split -l 10000 big.sql chunk_拆成万行一份的小文件(注意:按行拆可能切在语句中间,仅适用于纯 INSERT 且每行一条的导出格式) - 更可靠的方式是用
awk '/^INSERT INTO/ {n++} {print > "chunk_" int((n-1)/5000) ".sql"}' big.sql,按 INSERT 块切分 - 导入时加
-v参数观察当前执行到哪条语句,失败后用tail -n +N big.sql | mysql ...跳过已成功部分(N 是最后成功语句的行号) - 真正生产环境建议改用
mydumper/myloader工具链,它原生支持分表、并发、断点续传,比原生命令靠谱得多
导入速度慢得离谱,CPU 和磁盘都不高
看起来是 I/O 瓶颈,实际常是 MySQL 自身事务和索引机制拖慢了节奏。
- 导入前执行
SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; SET AUTOCOMMIT=0;,再导入,最后手动COMMIT;—— 这能提速 5–10 倍 - 如果 SQL 文件不含事务包装,可用
sed -i '1s/^/BEGIN;/; $s/$/; COMMIT;/' file.sql包一层(谨慎用于无错误风险的干净数据) - 禁用索引重建:
ALTER TABLE tbl_name DISABLE KEYS;导入后再ENABLE KEYS;,但需提前在 SQL 中替换对应语句 - 确认 MySQL 的
innodb_buffer_pool_size至少设为物理内存的 50%–75%,否则大量刷盘
SHOW PROCESSLIST 一边查 mysqld.err 日志,同时盯住 max_allowed_packet、事务控制、字符集三处是否对齐。漏掉任意一个,都可能让整个过程卡在某个无声的报错上。











