Navicat同步卡住、表打不开、界面灰掉,主因是源库异常重启或长事务残留引发MDL锁或InnoDB行锁未释放;需执行FLUSH TABLES WITH READ LOCK+UNLOCK TABLES清MDL缓存,查INNODB_TRX定位并KILL幽灵事务,人工对齐SHOW MASTER STATUS与同步日志中的binlog位点。
navicat 数据同步卡住、表打不开、界面灰掉——大概率不是网络或配置问题,而是同步过程中源库异常重启或长事务残留,触发了 mysql 的元数据锁(mdl)或 innodb 行锁未释放。直接重试或重启 navicat 无效,必须干预底层锁状态。
查 Waiting for table metadata lock 的真实进程
Navicat 同步卡在“正在加载”时,SHOW PROCESSLIST 返回的 State 列里往往藏着 Waiting for table metadata lock,但这个状态不会自动高亮,也不会出现在 Navicat 自身的 UI 提示中。
- 在 Navicat 中右键目标数据库 →「命令列界面」,执行
SHOW PROCESSLIST - 逐行检查
State字段:只要含metadata lock或Locked,且Time> 30 秒,就是可疑对象 -
Info列若显示ALTER TABLE、CREATE INDEX或同步相关的INSERT INTO ... SELECT,基本可确认是同步任务残留 - 注意 User 为
navicat或为空的连接,这类常是断连后未清理的幽灵会话
KILL 前先确认是否真有锁等待链
乱杀 KILL 可能中断正常事务,尤其当目标线程其实在做合法写入时。必须验证它是否真的阻塞别人。
- 执行
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX ORDER BY trx_started DESC LIMIT 5,看TRX_STATE是否为RUNNING,TRX_STARTED是否远早于当前时间(比如 > 5 分钟) - 再查锁等待:
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS,有返回结果说明存在明确等待关系 - 若
TRX_MYSQL_THREAD_ID对应的PROCESSLIST中INFO为空或USER为NULL,基本可判定是残留事务,可安全KILL - 避免杀
system user或event_scheduler类型线程,它们不参与业务锁竞争
源库重启后 MDL 锁没清,得用 FLUSH 强制刷新
源库意外重启后,MySQL 不会自动清理已失效的 MDL 锁引用,导致后续所有访问该表的操作全被挂起。此时 KILL 单个线程没用,因为锁本身还挂在元数据缓存里。
- 优先执行
FLUSH TABLES WITH READ LOCK,再立刻跟UNLOCK TABLES—— 这会清空所有未释放的表级 MDL 引用(需SUPER权限) - 若无
SUPER权限,改用FLUSH TABLES <code>table_name,对同步涉及的具体表逐个重载元数据 - 执行前先
FLUSH STATUS和FLUSH TABLES,确保内部统计和缓存一致,否则锁可能“假释放” - 该操作会短暂阻塞写入,选在低峰期操作;别用
KILL替代,它解决不了 MDL 缓存残留问题
binlog 位点错乱必须人工对齐
Navicat 同步依赖 binlog 位点或 GTID 推进,源库重启可能导致 gtid_executed 滞后或 mysql-bin.000xxx 切换不完整,造成同步逻辑反复比对、重复更新同一行,加剧锁冲突。
- 在源库执行
SHOW MASTER STATUS,记录当前File和Position(或Executed_Gtid_Set) - 翻 Navicat 同步日志,搜索最后成功同步的位点(通常含
binlog position:或GTID:字样) - 若两者不一致,手动在 Navicat 同步设置中修改起点位点,对齐到
SHOW MASTER STATUS的值 - 别依赖“重新同步”按钮,它不会修正位点偏差,只会从错误位置重放,可能引发主键冲突或死锁循环
真正麻烦的不是锁本身,而是锁背后的状态不一致:MDL 缓存、事务状态、binlog 位点三者不同步。任何一个环节没对齐,KILL 或 FLUSH 都只是临时缓解,几秒后又卡住。


















