线上问题之慢Sql一定是Sql慢吗

953 阅读2分钟

问题解答

答案是不。

就我现在的经验来分析,引起慢Sql的原因有两个
第一个,真的慢
第二个,大事务问题,你事务内一些操作,比如网络调用,把整体事务拖长,导致锁不释放

问题复盘

今天临近下班在钉钉收到两个线上预警,而且都是@我的。

第一个是调用推送Api超时了,我看了下,没怎么在意,觉得是偶发的网络拥堵情况吧。
第二个是慢sql,并且这个是update语句,重复相同的13个相同sql超时,但是就语句来看 应该是命中索引的,本身执行肯定快,成为慢sql肯定是资源被占用了。但是看了代码我也没发现什么特殊的地方(这个模块的推送我这期重构了改成异步了)。就认为是其他地方资源占用,导致这边被超时了。

但是后面我经验丰富的TL经过代码分析一下问题后,真相浮出水面。

这个问题Sql是在一个消息的消费者代码中,伪逻辑如下

//事务开始
修改订单信息(占用资源,其他线程阻塞)
修改对应订单车辆为起运
推送(超时了)
其他系统索引同步
//事务结束

一个订单有13辆车,当这13辆车一起发起起运时,会并发发送13个起运消息,当第一条消息消费的时候,推送方法超时了,10秒的timeout才返回,那么其他消费者就会阻塞在第一句修改的sql调用上。直到第一条消费结束,过了10多秒,其他的消费者才从阻塞中依次恢复。这批的sql也就变成了慢sql。

上面看似没有关联的两个告警联系到了一起,有意思。

以后对于线上告警,我要好好重视,都是学习的机会。

问题总结

不要在事务内运行除了数据库操作以外的会引起阻塞的调用,比如推送,发短息,同步索引这些操作,都进行异步解耦。

还有一个公司的监控系统真的是相当重要。

下面是我公众号,大家可以关注下。

image