Navicat同步卡在“Comparing records”阶段因缺失主键或UNIQUE NOT NULL索引,导致全量拉取+内存哈希排序,引发CPU飙升;须确保源目标表结构及索引完全一致,否则应先添加主键或改用增量同步。
Navicat数据同步卡在“Comparing records”阶段导致CPU飙升
这个阶段 navicat 并不是走数据库索引比对,而是在本地内存中对整张表做全量哈希计算和排序。一旦源表或目标表缺失主键或 unique not null 索引,它就会把全部记录 select 出来,在本地逐行比对 —— 这个过程完全吃 cpu,且 macos/linux 上更容易触发内存交换或 oom。
- 务必确认源表和目标表结构一致,且都有相同定义的主键或
UNIQUE NOT NULL索引;否则 Navicat 会自动降级为全量拉取 + 内存排序 - 同步前用
SHOW CREATE TABLE检查两边索引是否完全匹配,注意字段顺序、NULL 属性、字符集等细节 - 如果表确实无主键,别硬同步,先加主键或用
WHERE id > ? AND id 分批次手动切片
同步线程数设太高反而拖慢整体速度
Navicat 的「高级」设置里可以调并发线程数,但设成 8 或 16 不等于更快 —— 它受限于本地 HttpClient 连接池、MySQL 的 max_connections、甚至 Linux 的临时端口范围(/proc/sys/net/ipv4/ip_local_port_range 默认 32768–65535)。
- 实测多数局域网环境,设为 2~4 线程最稳;超过 6 线程后平均耗时常反升
- 检查 Navicat 日志里是否有
Connection refused或Too many open files报错,这是连接池或系统资源见顶的信号 - Windows 上表现略好,但若目标库在远程云服务器,网络延迟会放大线程争抢效应
为什么“低峰期执行”真有用,不只是心理安慰
Navicat 同步本身不直连磁盘,但它触发的 SQL 查询会竞争数据库锁、缓冲池和 CPU 调度。尤其当目标库正在跑报表、ETL 或其他写入任务时,INSERT ... ON DUPLICATE KEY UPDATE 或 REPLACE INTO 会频繁等待 MDL 锁或行锁,导致 Navicat 线程反复重试、空转消耗 CPU。
- 观察
SHOW PROCESSLIST,如果看到大量Waiting for table metadata lock或Updating状态,说明锁竞争已成瓶颈 - 避开业务高峰(如每天 9:00–11:30、14:00–16:00)能显著减少锁等待,让同步更“顺滑”而非“卡顿+重试”
- 如果必须白天跑,可在同步前手动执行
SET SESSION innodb_lock_wait_timeout = 30,避免单次等待太久拖垮整个任务
真正难处理的是无主键大表同步 —— 它既不能靠调线程数解决,也很难靠错峰规避,必须前置改造表结构或拆成带条件的子任务。这点容易被忽略,但却是 CPU 长期飙高最顽固的根因。











