如何确定SQL deadlock graph中SQL查询调用的原始先后顺序
关于SQL死锁图顺序与查询调用顺序的问题解答
死锁图的排列顺序和代码SQL出现顺序无关
死锁图从左到右的排列顺序完全不对应SQL在代码中的出现顺序,也不代表实际的调用先后。
死锁图的排序逻辑是数据库引擎基于死锁检测时捕获的资源持有、等待关系生成的,通常会优先展示被选中的死锁牺牲者节点,和事务/查询的发起顺序没有关联。
如何查询SQL调用的实际先后顺序
- 优先查死锁原始日志的时间戳字段:不要依赖可视化死锁图的排列,直接看死锁的原始文本/XML数据,所有主流数据库的死锁日志都会携带事务、语句的时间属性:
- 以SQL Server为例,死锁XML的
<process>节点自带lasttranstarted(事务启动时间)、lastbatchstarted(最后一次批处理发起时间)属性,直接比较两个事务的对应属性值,时间更早的就是先发起的查询 - 以MySQL为例,死锁日志中每个
TRANSACTION块会标注事务启动时间,配合performance_schema.events_statements_history表的历史记录,也能快速定位语句的实际执行顺序
- 以SQL Server为例,死锁XML的
- 结合应用侧的调用日志:如果需要对应到代码层面的调用顺序,可提前在应用层做埋点:每个SQL请求绑定唯一的链路ID,打印日志时携带链路ID、请求发起时间、SQL片段,死锁发生后用死锁日志里的SQL特征、会话参数匹配应用日志,就能直接拿到代码中的调用先后,还能关联到上游业务请求上下文
- 针对你提到的「查询1先发起、查询2后发起触发死锁」的场景,直接提取死锁日志中两个事务的启动时间/语句执行时间做排序,就能直接得到实际调用顺序,不需要参考死锁图的排列。
内容的提问来源于stack exchange,提问作者variable
相关产品推荐
相关产品推荐

