核心原因是目标数据库所在磁盘已满,而非Navicat本地空间不足;必须登录目标环境执行df -h检查数据库数据目录挂载点(如/var/lib/mysql对应/或/var分区),若Use%≥95%或Avail为0即为根源。
navicat 同步失败报 no space left on device,核心原因不是同步逻辑出错,而是目标数据库所在磁盘已满——哪怕你本地 navicat 还有空间,只要 mysql/postgresql 的数据目录挂载点满了,同步就会卡在写入阶段。
检查目标库实际磁盘使用率,别只看本地C盘
很多人只检查自己电脑的 C 盘,但 Navicat 同步的目标库通常在远程服务器(或 Docker 容器、WSL 子系统)里。必须登录目标环境执行:
df -h
重点关注 Mounted on 列中数据库数据目录所在的挂载点,例如:
- MySQL 默认数据路径一般挂载在
/var/lib/mysql→ 对应/或/var分区 - PostgreSQL 常在
/var/lib/postgresql→ 同样归属根分区或独立/var - 若用 Docker,运行
docker exec -it查容器内磁盘df -h
如果某分区 Use% 达到 95%+,尤其 Avail 显示为 0,这就是根源。
同步前清理数据库服务自身日志文件
数据库运行时持续产生日志,最容易吃掉空间的是二进制日志(binlog)、慢查询日志(slow.log)、错误日志(error.log)和审计日志(Oracle 的 audit_file_dest)。不能直接删,得按服务规范清理:
- MySQL:登录后执行
RESET MASTER(清空所有 binlog,慎用)或PURGE BINARY LOGS BEFORE '2026-04-15 00:00:00'(保留最近7天) - 确认日志开关状态:
SHOW VARIABLES LIKE 'log_%';,关掉非必要日志如log_output='TABLE'可能导致mysql.general_log表暴涨 - PostgreSQL:检查
log_directory和log_filename配置,手动删除旧日志前先pg_ctl stop -m fast或确保log_rotation_age已启用 - Oracle:查
SELECT value FROM v$parameter WHERE name = 'audit_file_dest';,清空该路径下过期.aud文件
扩容操作要区分场景,别盲目扩展根分区
扩容不是“加块硬盘”就完事,得看部署形态:
- 云服务器(阿里云/ECS、腾讯云/CVM):优先在控制台「云盘扩容」→ 在线扩容 → 登录后执行
resize2fs /dev/vda1(ext4)或xfs_growfs /(xfs),无需重启 - Docker 容器:别改容器内磁盘,应重建容器并挂载更大容量的卷(
-v /data/mysql:/var/lib/mysql),或改用 hostpath 指向宿主机大分区 - 物理机/VMware:若
/var/lib/mysql单独挂载,可直接扩对应 LVM 逻辑卷;若混在/下,扩根分区风险高,建议迁移数据目录到新磁盘 - 切忌对正在同步的库做 LVM 扩容或 fsck,可能中断事务导致同步失败甚至主从不一致
同步任务本身可降低空间压力
Navicat 同步默认走临时表 + INSERT SELECT,中间会生成大量临时文件。可在同步前干预:
- 在 Navicat 同步设置里勾选「使用 INSERT...ON DUPLICATE KEY UPDATE」而非「REPLACE INTO」,减少临时索引重建开销
- 关闭「比较结构」和「比较数据」中的「BLOB/TEXT 字段」比对(除非真需要),避免加载大字段进内存
- 如果目标库支持,提前执行
SET SESSION sort_buffer_size = 2*1024*1024;和SET SESSION read_buffer_size = 1024*1024;,缓解排序/读取时的磁盘临时文件生成 - 对超大表,改用命令行分批同步:
mysqldump --where="id BETWEEN 1 AND 100000" ... | mysql ...
真正容易被忽略的是:数据库服务进程本身对磁盘空间的“感知延迟”。即使你刚删了 10GB 日志,df 立刻显示可用空间,但 MySQL 可能还缓存着已删除文件的句柄(lsof | grep deleted 可见),此时需重启 mysqld 才彻底释放。同步前务必确认这点。











