MySQL 锁表故障排查与处理 1、概述MySQL 锁表通常不是表真的坏了而是有会话长时间持有锁导致其他操作被阻塞。排查思路是先定位阻塞源再决定终止或优化最后从 SQL、事务和索引层面预防。2、常见原因原因典型表现说明事务未提交INSERT/UPDATE/DELETE 卡住BEGIN后没有COMMIT/ROLLBACK锁一直不释放长事务连接堆积、超时事务中执行远程调用、文件 IO、大批量处理索引缺失行锁退化为表锁更新/删除未命中索引InnoDB 可能扫描更多行DDL 冲突ALTER TABLE卡住DDL 需要 MDL 写锁会被未提交事务阻塞显式锁表表无法写入使用了LOCK TABLES ... WRITE但未解锁存储引擎问题并发差MyISAM 默认表锁高并发下容易阻塞唯一键/热点行冲突INSERT 等待并发写入同一唯一键或同一行锁竞争加剧3、排查与处理3.1先看谁在阻塞-- 查看当前连接和卡住的 SQL SHOW FULL PROCESSLIST; -- 查看活跃事务重点找运行时间长的事务 SELECT * FROM information_schema.INNODB_TRX; -- 查看被占用的表 SHOW OPEN TABLES WHERE In_use 0;3.2MySQL 8.0 推荐这样查锁等待-- 直接看阻塞关系 SELECT * FROM sys.innodb_lock_waits; -- 或查 performance_schema SELECT * FROM performance_schema.data_lock_waits;重点关注blocking_pid它就是持有锁的会话。3.3如果是 MDL 锁常见现象是大量会话处于Waiting for table metadata lock可查SELECT * FROM performance_schema.metadata_locks;通常要找到持有该表 MDL 锁的旧事务并终止。3.4终止阻塞会话确认不是核心业务长事务后KILL blocking_pid;注意KILL会触发事务回滚如果该事务修改数据很多回滚本身也需要时间。4、根本解决方案缩短事务事务里不要做 HTTP 调用、文件处理、复杂计算核心事务尽量控制在几秒内。拆分大事务批量更新/删除/插入按 5001000 条分批提交。补索引确保UPDATE/DELETE的WHERE条件命中索引避免全表扫描。统一加锁顺序多表更新时按固定顺序访问降低死锁概率。使用 InnoDB避免 MyISAM 表锁问题。谨慎执行 DDL避开业务高峰必要时使用在线 DDL 工具。调整超时参数可适当调小innodb_lock_wait_timeout让异常请求快速失败避免连接堆积。5、术语释义MDLMetadata Lock元数据锁MySQL Server 层用于保护表结构元信息的锁。DMLData Manipulation Language数据操纵语言用于增删改查SELECT/INSERT/UPDATE/DELETE。DDLData Definition Language数据定义语言用于修改表结构ALTER/DROP/CREATE/TRUNCATE/RENAME。InnoDBMySQL 主流存储引擎支持事务、行锁、MVCC、外键。MyISAMMySQL 早期存储引擎不支持事务使用表级锁并发写入性能差。RCRead Committed读已提交事务隔离级别之一。RRRepeatable Read可重复读InnoDB 默认的事务隔离级别。