lock wait timeout exceeded 表示事务等待行锁超时(默认50秒),本质是被其他长事务或未提交操作阻塞,并非数据库性能问题;需通过innodb_trx和performance_schema定位锁源,排查索引缺失、mdl锁及锁链式等待。

Lock wait timeout exceeded 是锁没抢到,不是数据库卡了
这个错误本质是:当前事务在等某一行的锁,但等太久(默认50秒)被 MySQL 主动放弃了。它不反映 CPU 或磁盘忙,而是明确告诉你——有别的事务正霸占着你要改的数据,且迟迟不放手。
常见现象包括:UPDATE 卡住、DELETE 报错、甚至看似无害的 INSERT(尤其批量插入时受 innodb_autoinc_lock_mode 影响);开发常误以为“SQL 慢”,其实慢的是等锁,不是执行本身。
- 先查锁等待源头:运行
SELECT * FROM information_schema.INNODB_TRX;看哪些事务在跑、持续多久、在执行哪条 SQL - 再查谁在堵路:配合
SELECT * FROM information_schema.INNODB_LOCK_WAITS;和INNODB_LOCKS(MySQL 5.7+ 已移除,需用performance_schema.data_locks替代)定位阻塞者 - 别只盯慢日志:锁等待超时的 SQL 可能本身很快,只是前面被卡住了;重点看
trx_started时间和trx_state = 'LOCK WAIT'的记录
长事务和未提交操作是最常见的“锁源”
一个开了 3 分钟还没 COMMIT 或 ROLLBACK 的事务,会一直拿着行锁不放。哪怕它只 update 了一行,后续所有想碰这行的请求都会排队等它——直到超时。
典型场景:调试时手动开启事务后忘记提交;Spring 中 @Transactional 方法里调用了耗时外部服务(如 HTTP 请求),导致事务悬停;或代码异常跳出但没触发回滚逻辑。
- 检查应用层是否做了显式事务控制,尤其注意 try-catch 后缺
transaction.rollback() - MySQL 侧可临时设低阈值暴露问题:
SET SESSION innodb_lock_wait_timeout = 5;(仅会话级,不影响全局) - 避免在事务中做非 DB 操作:RPC、文件读写、sleep() 都应移出事务边界
索引缺失会让锁从“行级”升级成“伪表级”
没有合适索引时,MySQL 找不到目标行,只能全表扫描——过程中会对扫到的每一行加锁(即使最后不修改)。结果就是:你只想改 ID=123 的用户,却锁住了 80 万行,其他事务一碰这张表就卡。
比如 UPDATE user SET status=1 WHERE phone='138...' AND deleted=0,若 phone 或组合条件没索引,就会触发大面积锁定。
- 用
EXPLAIN看执行计划:如果type是ALL或index,且rows极高,基本就是索引问题 - 优先建联合索引而非单列索引,顺序按 WHERE 条件选择性从高到低排列(如
deleted, phone比phone, deleted更利于过滤已删除数据) - 注意隐式类型转换:
WHERE phone=138...(数字) vs 字段是VARCHAR,会导致索引失效,锁范围扩大
DDL 操作期间的元数据锁(MDL)容易被忽略
ALTER TABLE、ADD INDEX 这类操作会持有元数据锁,阻塞后续所有 DML(哪怕只是简单 SELECT)。此时报的也是 Lock wait timeout exceeded,但根源不是行锁,而是 MDL 等待。
尤其当大表加索引未完成时,后面所有对该表的增删改都会排队,且不显示在 INNODB_TRX 里——容易误判为“没人在操作”。
- 查 MDL 锁:
SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA = 'db_name' AND OBJECT_NAME = 'table_name'; - 看 DDL 是否卡住:
SHOW PROCESSLIST中状态为Waiting for table metadata lock的线程就是受害者 - 线上慎用阻塞式 DDL;优先考虑
ALGORITHM=INPLACE, LOCK=NONE(需版本支持),或用 pt-online-schema-change 等工具
真正难排查的,往往是“锁链式等待”:A 等 B,B 等 C,C 又等 A 回滚——这种环形依赖不会立刻报错,但会让多个事务同时僵住。这时候光看单个超时日志没用,得连起来看事务链和锁持有关系。别只盯着报错那条 SQL,它大概率只是最后一环。











