生产环境MySQL死锁本地复现失败,求排查思路
MySQL死锁根源排查思路求助
错误场景
遇到的死锁错误信息:
SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction (SQL: update `pre_txns_2403` set `status` = SUCCESS, `response_code` = 0, `response_msg` = SUCCESS, `ipay_error` = TXN, `ipay_desc` = Transaction Successful, `sp_transid` = 407508316340, `opr_id` = 407508316340, `res_dt` = 2024-03-15 08:00:14, `optional1` = 607264, `optional2` = 9935558558, `optional3` = CENTRAL BANK OF INDIA, `optional4` = 5044.00, `optional5` = e46944ca4251477b92842311c55f5e1e, `optional6` = , `optional7` = , `optional8` = , `optional9` = , `remarks1` = 316340, `remarks2` = , `remarks3` = , `remarks4` = YWY3OTAzYzNlM2ExZTJlOdjuLnfS78RXTDsN1fnMZcU=, `remarks5` = 3991805, `remarks6` = 431501, `remarks7` = 64a43d40-642e-4fa1-84d1-3f7034aa34c2, `remarks8` = , `remarks9` = , `remarks10` = , `remarks11` = , `remarks12` = , `remarks13` = , `remarks14` = , `remarks15` = LARAVEL where `ipay_id` = P240315080011LZNVJ)
触发代码逻辑
try { DB::connection($db . '__write')->beginTransaction(); $transaction = DB::connection($db . '__write')->table($table)->where('ipay_id', $validatedData['ipayId']); $transaction->update($data); DB::connection($db . '__write')->commit(); } catch (\Exception $e) { return \Ipay::response([ 'statusCode' => 'ISE', 'internalCode' => $e->getMessage(), 'internalCodeAppend' => '#UTU1', ]); }
现有困惑
本地环境完整复现操作,甚至1秒内执行10次脚本都未出现死锁,但生产环境触发该错误。目前仅能拿到上述错误信息,无法确定死锁是由该更新查询导致,还是存在其他关联操作影响。
求助需求
需要死锁根源追踪、排查的实用思路与方法,以及分析死锁发生前相关查询序列的有效手段。可提供脚本执行的所有查询序列作为补充上下文。
排查思路参考
- 提取生产环境死锁日志
执行SHOW ENGINE INNODB STATUS;,查看输出中LATEST DETECTED DEADLOCK部分,这里会明确死锁涉及的事务、锁类型、关联行与索引信息,是定位核心依据。若生产开启了通用日志或慢查询日志,可筛选死锁时间点前后的SQL,排查是否有其他事务在操作同一张表的相关数据。 - 检查索引与锁范围
确认pre_txns_2403表的ipay_id字段是否有有效索引:无索引会导致UPDATE触发全表扫描,加大量行锁甚至表锁,大幅提升死锁概率;有索引的话,用EXPLAIN分析该UPDATE语句,确认索引是否被正确使用。同时排查是否有其他事务操作该表时,因索引使用问题导致锁范围扩大引发冲突。 - 模拟生产级并发场景
本地复现失败大概率是并发量、数据库配置(如事务隔离级别、innodb_lock_wait_timeout)与生产不一致:调整本地数据库配置匹配生产,用并发测试工具(如JMeter、自定义多线程脚本)模拟更高并发量,同时加入生产中可能存在的关联操作(如同一表的其他更新、关联表的读写),尝试复现死锁。 - 梳理完整事务执行链路
整理生产中该业务的全流程事务序列,排查是否存在交叉锁等待场景:比如事务A先通过SELECT ... FOR UPDATE锁定目标行,再执行其他耗时操作;事务B同时发起UPDATE请求等待锁,若此时事务A又尝试获取其他资源锁,就可能形成死锁。
内容的提问来源于stack exchange,提问作者Rohannn Singh
相关产品推荐
相关产品推荐

