背景:系统中某个查询接口报错,查看日志发现是获取锁超时,疑似死锁问题。
数据库:MySQL8.0.13,InnoDB引擎。
处理步骤:
1.show OPEN TABLES where In_use > 0;
查看表锁定情况,定位具体表
2.show engine innodb status;
查看引擎状态,在文本中搜索LATEST DETECTED DEADLOCK,定位引起超时的具体SQL及进程id等信息
3.show processlist;
查看进程列表,根据id寻找阻塞进程
4.kill 进程id
杀死阻塞进程
锁超时原因:同事通过Yearning平台提交过一次SQL工单,是百万级的数据删除,涉及in和子查询导致效率更加低,执行一天后工单显示超时失败,计划后续采用代码分批删除方式处理。但该删除SQL进程并未随着工单失败而终止,10多天仍在执行,表中部分行被长期锁定。另有一查询SQL的结果包含这些数据,并需要通过for update加锁,就报获取锁超时了。删除SQL长期未能执行完是否为死锁问题仍需排查。
总结:InnoDB存储引擎检测到死锁时,通常会选择undo量最小的事务进行回滚,kill进程是治标之策,找到死锁产生的原因才是关键。