应执行FLUSH TABLES WITH READ LOCK+UNLOCK TABLES清MDL锁,查INNODB_TRX定位幽灵事务并KILL,人工对齐binlog位点,且先FLUSH STATUS和FLUSH TABLES刷新元数据缓存。
navicat 16 数据同步卡住,大概率不是数据库慢或网络断了,而是客户端线程被同步阻塞、连接状态错乱、锁未释放或批次设置失当——直接重启软件往往治标不治本。
同步卡在“Waiting for table metadata lock”怎么办
这是 MySQL 表元数据锁残留导致的典型卡死,源库重启、长事务中断或 DDL 操作未完成都可能留下幽灵锁。Navicat 自身无法感知并清理,必须人工干预:
- 先执行
FLUSH TABLES WITH READ LOCK,再立刻执行UNLOCK TABLES(需SUPER权限),强制刷新 MDL 缓存 - 若无权限,改用
FLUSH TABLES table_name(替换为实际表名),单表触发元数据重载 - 查残留事务:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_STATE = 'RUNNING' AND TRX_STARTED - 对确认已失效的
TRX_MYSQL_THREAD_ID,执行KILL thread_id(不是KILL QUERY)
同步中途卡死且 UI 完全无响应
Navicat 16 是单线程同步架构,UI 线程直接阻塞等待 JDBC/ODBC recv() 返回完整结果。此时右键、Ctrl+R、切换 Tab 全部失效,任务管理器显示进程“正在运行”但 CPU 占用仅 10%~15%,磁盘 I/O 持续活跃:
- 不要等,也不要用任务管理器强行结束 —— 这会留下未释放的文件句柄或锁
- 先尝试关闭所有打开的查询窗口和表标签页
- 右键对应连接 →
断开连接→ 再右键 →连接重建会话 - 若仍失败,右键连接 →
复制连接→ 删除原连接 → 将新连接重命名为原名,清空内部缓存状态
同步千万级数据时内存持续飙高甚至崩溃
Navicat 16 不基于 JVM,-Xms/-Xmx 参数完全无效;所谓“调 JVM”是混淆了 Navicat 和 DBeaver 等 Java 工具:
- 在「数据传输」向导的「高级」页签中,把「每批记录数」设为
5000~10000:低于 5000 事务太碎,高于 20000 易触发内存峰值 - 右键目标连接 →「编辑连接」→「高级」→ 勾选「压缩协议」(MySQL/PostgreSQL 支持),降低网络传输体积
- 取消勾选「同步触发器」「同步存储过程」等非必要元数据项,它们会额外加载 SQL 并多次查询
- 若任务管理器中
navicat.exe的私有工作集持续超过1.2 GB,说明字段含大文本/BLOB 或批次过大,应立即中止并拆分条件
同步卡在 “Comparing records” 阶段且 CPU 占满
这个阶段 Navicat 在本地内存做全量哈希比对,前提是源表和目标表都有主键或 UNIQUE NOT NULL 索引。一旦缺失,它就会拉取整张表到本地排序,CPU 和内存双双暴走:
- 用
SHOW CREATE TABLE分别检查两边表结构,确认主键定义、字段顺序、NULL 属性、字符集完全一致 - 若表确实无主键,别硬同步 —— 先加主键,或用
WHERE id > ? AND id 手动分片 - 并发线程数建议设为
2~4:设太高反而触发连接池耗尽、端口复用冲突,日志里出现Too many open files就是信号 - 避开业务高峰(如 9:00–11:30)执行,减少与报表、ETL 任务的锁竞争
真正难处理的是无主键大表 + 跨服务器 + WAL 模式 SQLite 文件锁共存的组合场景——这些点各自单独出现尚可绕过,叠加时几乎必然卡死,必须前置拆解,而不是指望同步界面里的某个开关能一键解决。


















