Navicat 15 备份大表时触发 OutOfMemoryError 的根本原因是其GUI进程将整表SELECT结果全量加载至内存拼装INSERT语句并压缩,而非调用mysqldump等流式工具;关闭“压缩备份文件”和“保存为单个文件”、改用mysqldump或调大JVM堆内存可有效解决。

Navicat 15 备份大表时触发 OutOfMemoryError,根本不是数据库导出慢,而是 Navicat 自己把整张表 SELECT 出来后,在内存里缓存、拼接、渲染、再压缩——这个过程完全绕不开 GUI 进程的堆限制。
为什么“备份”比“查询”更容易崩
Navicat 的「备份数据库」功能底层其实是执行 SELECT * FROM table_name + 内存拼装 SQL INSERT 语句,而非调用 mysqldump 或 pg_dump。它会:
- 一次性拉取全部数据(不走流式游标),哪怕你只勾选一张 500 万行的表
- 为每一行生成带引号、转义、字段名的完整
INSERT字符串,并存入ArrayList<String> - 最后统一 gzip 压缩,而压缩前所有字符串仍驻留在堆中
- 32 位 Navicat 或默认
-Xmx512m配置下,2GB 表数据在内存中膨胀到 4–6GB 很常见
关掉“自动压缩”和“保存为单文件”能立刻减压
这两个选项是内存杀手,但藏得深:
- 右键表 →「备份数据库」→ 点「高级」→ 取消勾选
压缩备份文件(压缩动作本身吃 CPU+内存,且必须等全部 INSERT 拼完才开始) - 同页面取消勾选
将备份保存为单个文件→ 改为每个表一个文件,这样 Navicat 会逐表执行、逐表释放内存 - 如果目标是迁移,直接选
SQL 格式而非Navicat 备份格式(.ncb),后者要序列化更多元数据
用 mysqldump 替代 Navicat 备份(推荐)
这是最稳的解法,绕过所有 GUI 层内存模型:
- 先确认你有命令行权限:
mysqldump -V输出版本 ≥ 5.7 - 执行(Windows 示例):
mysqldump -u root -p -h 127.0.0.1 --single-transaction --skip-triggers --no-create-info database_name table_name > table_backup.sql - 关键参数说明:
--single-transaction避免锁表;--skip-triggers防止触发器元数据加载;--no-create-info不导建表语句,只导数据,大幅减少内存解析压力 - 大表加
--where="id BETWEEN 1 AND 100000"分段导出,配合split -l 50000后续合并
真没法切命令行?调 JVM 参数 + 关服务端缓存
仅限 Windows/macOS 64 位 Navicat 15,且你有安装目录写权限:
- 编辑
navicat.ini(通常在C:\Program Files\PremiumSoft\Navicat Premium 15\或~/Applications/Navicat Premium.app/Contents/MacOS/) - 找到
-Xmx512m行,改为-Xmx1024m(不要超过物理内存的 1/2) - 同时添加一行:
-XX:+UseG1GC(G1 垃圾回收器对大堆更友好) - 关闭 Navicat 所有窗口 → 任务管理器杀掉残留进程
navicat和java→ 重启 - 额外建议:右键连接 →「连接属性」→「高级」→ 把
Fetch Size设为500(强制分页拉取,虽对备份主流程影响有限,但能降低首次 SELECT 峰值)
真正容易被忽略的是:Navicat 15 的「备份」操作一旦开始,就不再响应 UI 中断信号——点「取消」只是隐藏进度条,后台线程仍在拼命拼字符串。所以与其等它崩,不如一开始就绕开。


















