navicat 15 同步超大型表时卡死是因无流式读取,所有数据全量加载内存导致oom;应手动设每批记录数为5000~10000、禁用比较数据、显式指定字段、导出sql文件后命令行导入。
navicat 15 同步超大型表时进度条卡死,不是界面假死,而是它根本没做流式读取——所有数据都得先全量加载进内存再发往目标库,一旦表含大字段或行数超千万,本地内存很快打满,ui 线程被拖住,连取消操作都响应不了。
Navicat 15 压根不支持流式查询
你找不到“流式查询”开关,是因为它不存在。所谓“每批记录数”只是控制 INSERT 分段提交的粒度,不是分页拉取:每一批仍会把整批结果集(含 TEXT/BLOB 字段)完整载入内存,处理完才释放。源表和目标表的主键+比对字段还会额外缓存做哈希匹配,进一步吃内存。
-
SELECT *是最危险操作——哪怕只同步 10 万行,带TEXT字段就可能占掉 2GB+ 内存 - “自动保存查询”历史、打开过的大结果集标签页,会持续持有内存引用,关 tab 不清
- 勾选了“直接表/视图复制”,Navicat 仍要先加载元信息、构建映射结构、校验字段兼容性——这些都在内存里干
真正能压低内存的实操配置
别信默认值,手动锁死关键参数:
- 在“数据传输”向导中,把
每批记录数设为5000~10000(大于 2 万极易本地 OOM;小于 1000 则网络往返开销陡增) - 关闭
比较数据和同步时间戳——它们会额外加载字段进内存逐行比对 - 显式排除大字段:
SELECT id, name, created_at FROM t_user,绝不用SELECT * - 先导出为 SQL 文件(勾选
仅 INSERT+禁用外键检查),再用命令行导入:mysql -u root -p database_name
为什么改用命令行能绕过卡死
命令行不走 Navicat 的 GUI 内存池,也不缓存执行计划或进度状态。mysqldump 加 --single-transaction 可避免锁表,加 --skip-extended-insert 能防止单条 INSERT 过长触发 max_allowed_packet 错误,而 Navicat 封装层把这些关键开关全藏掉了。
- Navicat 备份 >1GB 文件时,常因内部缓冲区溢出报
Packet for query is too large;命令行直连无此限制 - 远程同步走 SSH 隧道时,Navicat 的日志重定向 + 状态轮询机制极易在高延迟下挂起;
mysqldump输出是原始流,更稳定 - 超过 50GB 的库,Navicat 全库同步必然失败——它不支持并行、不能暂停续传、无法按表分文件
最常被忽略的一点:你以为卡在“同步中”,其实早在你点“开始”前,Navicat 就已把源表全量读进内存做预处理了。只要表结构或数据量超出本地物理内存余量,卡死就是确定性结果,调任何超时参数都没用。











