等待不是根因
Lock wait timeout exceeded 表示某个事务等待锁太久。修复不一定是更大的超时,通常是更短的事务、更好的索引或一致的访问顺序。先用 SHOW ENGINE INNODB STATUS 或 performance_schema 找出等待者和阻塞者。
SELECT trx_id, trx_state, trx_started, trx_query
FROM information_schema.innodb_trx
ORDER BY trx_started;
查找长事务和宽锁
调用外部 API 的事务会在整个调用期间持锁。UPDATE ... WHERE status = ... 缺少索引可能锁住很多行而不是少数行。DDL 语句可能等待 idle-in-transaction 会话持有的元数据锁,从而阻塞整张表的所有查询。
修复与验证
缩短事务、为谓词建索引,并在更新前对 id 排序。对幂等操作,为死锁(1213)和锁等待添加有界重试。用两个会话复现并做并发测试验证。监控 innodb_row_lock_time 和最老事务年龄;最老事务年龄上升是早期预警。