批量对账任务跑起来十分钟后,update 报 1205 Lock wait timeout exceeded,innodb_lock_wait_timeout 是 50。同一时刻接口 P99 冲到 60 秒。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
SELECT trx_id, trx_state, trx_started, trx_query FROM information_schema.innodb_trx ORDER BY trx_started LIMIT 5; SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';
另一个事务拿着同一批行的排他锁没提交,后来的更新只能进等待队列。等待超过阈值就抛 1205,业务层没有重试,整批任务停在那里。长事务多半来自一个忘了提交的循环。这一点先确认清楚,后面就不用反复试。
「锁等待 1205」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
改完隔一天再看一次,当场正常不代表能稳住。
具体做法是,先查 innodb_trx 找出运行时间最长的那个事务;再看 data_locks 确认它锁的是哪几行;把大事务拆小 每批提交一次 别把一万行放进一个事务;给批量任务加重试和退避 遇到 1205 隔一秒再来。
改完照着核一遍,最长的 trx_started 不再超过几秒 批量任务跑完没有 1205 接口 P99 跟着回落。
