先执行show processlist查locked、sending data、waiting for table metadata lock且time>60秒、info含目标表、user/host非当前连接的线程,kill其id;再查information_schema.innodb_trx找trx_state=lock wait或trx_started超时的事务,kill trx_mysql_thread_id;调低导入批次、禁用多线程;kill后须等待10–20秒再验证。

直接查 SHOW PROCESSLIST 筛三类关键状态
Navicat 卡住时,别点重试或调隔离级别,先开新查询窗口执行 SHOW PROCESSLIST。重点盯这三类线程:
-
Status是Locked、Sending data或Waiting for table metadata lock -
Time超过 60 秒,且Info明显涉及你正操作的表(比如UPDATE user SET ... WHERE id = 123) -
User和Host不是你当前 Navicat 连接(避免误杀自己)
符合全部条件的 ID 就是阻塞源头,立刻 KILL 12345(把 12345 换成实际 ID)。这不是暴力清场,是移开挡在 DDL 或长事务前面的石头。
用 INFORMATION_SCHEMA.INNODB_TRX 找静默挂起的事务
SHOW PROCESSLIST 只能看到“正在跑”的线程,但一个没 COMMIT 的事务可能已静默挂起数小时。运行:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), TRX_STARTED)) > 60;
重点关注:
-
TRX_STATE是lock wait→ 它正卡着等锁,上游有持锁者 -
TRX_STARTED时间异常久 → 很可能是开发/测试环境忘记提交的事务 -
TRX_QUERY显示具体 SQL → 判断是否可安全终止(比如只是个SELECT ... FOR UPDATE测试)
确认无业务影响后,KILL 对应的 TRX_MYSQL_THREAD_ID,不是 KILL QUERY——后者只中断语句,事务还活着,锁照挂。
别信 Navicat 同步界面里的「Transaction Isolation Level」
那个下拉菜单设成 READ COMMITTED 对解决锁等待完全无效,原因很实在:
- 它只影响同步脚本内部生成的
SELECT/INSERT的可见性,对ALTER TABLE这类 DDL 毫无作用 - MDL 锁在任何隔离级别下都会被 DDL 强制申请,且与 DML 事务互斥
- Navicat 导入默认
AUTOCOMMIT=1,LOCK TABLES在这种模式下瞬间失效
真正该动的是操作节奏:把「每批提交记录数」从 1000 降到 100,关掉「启用多线程导入」——减少单次锁持有时间,也避免自己跟自己抢锁。
查完 KILL 后必须等 10–20 秒再验证
特别是表行数 > 500 万时,MySQL 回滚或释放锁需要真实耗时。立刻再跑 SHOW PROCESSLIST 或 SHOW OPEN TABLES WHERE In_use > 0,很可能看到“锁还在”,其实是假阳性。等够时间再查,否则容易重复 KILL、误判、甚至引发二次阻塞。











