navicat导出含大blob/text表易卡死或报错,因其默认sql格式将blob转为膨胀的十六进制字符串并在内存拼装整行,触发oom或“packet too large”;应改用mysqldump(配--hex-blob --skip-extended-insert --single-transaction)或更优的load data infile文本中转方案。

直接结论:别用Navicat导出含大BLOB/TEXT的表,改用mysqldump加关键参数,或更优——用LOAD DATA INFILE配合文本格式中转。
为什么Navicat在BLOB/TEXT面前容易卡死或报错
Navicat导出时默认生成SQL格式,对BLOB字段会转成0x...十六进制字符串,体积翻倍;同时它在内存里拼装整行数据,遇到几十MB的单个BLOB就可能OOM。常见错误是Packet too large或界面无响应,本质是客户端内存+MySQL协议包限制双重踩坑。
-
max_allowed_packet服务端限制必须调大(比如设为256M),否则mysqldump或Navicat都会在传输阶段被拦住 - Navicat不暴露
--net_buffer_length等底层参数,无法控制批量发送节奏,而命令行工具可以 - GUI工具缺乏对“跳过索引重建”“禁用外键检查”等导入加速手段的支持
用mysqldump导出大BLOB表的最小有效参数组合
绕过默认低效行为,重点压缩SQL体积、减少解析压力、适配二进制字段:
- 必加
--hex-blob:把BLOB转成紧凑的十六进制字面量(如0x89504E47),比base64短且避免转义混乱 - 禁用
--extended-insert(即加--skip-extended-insert):每行独立INSERT,降低单条语句长度,避免超max_allowed_packet - 加
--single-transaction保障InnoDB一致性,但不锁表 - 加
--skip-autocommit --net_buffer_length=1048576:让客户端一次发1MB数据包,减少网络往返
完整命令示例:
mysqldump --single-transaction --skip-extended-insert --skip-autocommit --net_buffer_length=1048576 --hex-blob -u root db_name table_with_blob > dump.sql
真正快的方案:绕过SQL,走LOAD DATA INFILE文本中转
当BLOB字段数量多、单个体积大(>1MB)、且允许临时落地文件时,SELECT ... INTO OUTFILE + LOAD DATA INFILE比任何SQL导出都快一个数量级——因为它跳过了SQL解析、字符集转换、事务包装所有开销。
- 导出前确认
secure_file_priv路径(用SHOW VARIABLES LIKE 'secure_file_priv';查),只能写入该目录 - 用
SELECT id, HEX(blob_col), text_col FROM t INTO OUTFILE '/var/lib/mysql-files/t_data.txt' FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n';,把BLOB转HEX字符串存文本 - 导入时建好表后执行:
LOAD DATA INFILE '/var/lib/mysql-files/t_data.txt' INTO TABLE t (id, @blob_hex, text_col) SET blob_col = UNHEX(@blob_hex); - 注意:
UNHEX()只接受偶数长度十六进制串,导出前可用LPAD(HEX(blob_col), 2, '0')补位防错
导入时提速的关键不是“怎么读SQL”,而是“怎么少干活”
即使有了优化过的dump文件,直接mysql -u root db 仍慢——因为默认每条INSERT都触发日志刷盘、索引更新、约束检查。必须手动干预:
- 导入前执行:
SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0; - 导入完成后立刻执行:
SET unique_checks=1; SET foreign_key_checks=1; COMMIT; - 如果表已有大量索引,先
DROP INDEX,导入完再CREATE INDEX,速度差异可达5–10倍 - 对InnoDB表,临时把
innodb_flush_log_at_trx_commit设为0(仅限导入期间!),能显著减少redo log刷盘等待
这些操作没法在Navicat里点几下完成,必须进MySQL命令行或脚本封装。真正的瓶颈从来不在“数据有多大”,而在“你让MySQL重复做了多少遍本可省略的事”。











