线上问题之慢Sql一定是Sql慢吗
2018-11-23 本文已影响28人
土豆肉丝盖浇饭
问题解答
答案是不。就我现在的经验来分析,引起慢Sql的原因有两个,第一个,真的慢,第二个,资源被别人占用,锁不释放,导致我们的sql一直阻塞,变成慢sql。那么,为什么资源会被一直占用么,那就说明你的事务时间太长,可能是其他运行的sql慢或者其他的IO操作阻塞(比如Http调用)。
问题复盘
今天临近下班在钉钉收到两个线上预警,而且都是@我的。
第一个是调用推送Api超时了,我看了下,没怎么在意,觉得是偶发情况吧。
第二个是慢sql,并且这个是update语句,重复相同的13个相同sql超时,但是就语句来看 应该是命中索引的,本身执行肯定快,成为慢sql肯定是资源被占用了。但是看了代码我也没发现什么特殊的地方(这个模块的推送我这期重构了改成异步了)。就认为是其他地方资源占用,导致这边被超时了。
但是后面我经验丰富的TL经过代码分析一下问题后,真相浮出水面。
这个问题Sql是在一个消息的消费者代码中,伪逻辑如下
//事务开始
修改订单信息(占用资源,其他线程阻塞)
修改对应订单车辆为起运
推送(超时了)
其他系统索引同步
//事务结束
一个订单有13辆车,所以有13个起运消息发动过来,并且是并发的,当第一条消息消费的时候,推送方法超时了,10秒的timeout才返回,那么其他消费者就会阻塞在第一句修改的sql调用上。直到第一条消费结束,过了10多秒,其他的消费者才从阻塞中依次恢复。
上面看视没有关联的两个告警联系到了一起,不过我没看出来的问题,我觉得还是因为我这个版本已经重构掉了。。不是现场的代码。
以后对于线上告警,我要好好重视,都是学习的机会。
问题总结
不要在事务内运行除了数据库操作以外的会引起阻塞的调用,比如推送,发短息,同步索引这些操作,都进行异步解耦。
还有一个公司的监控系统真的是相当重要。
下面是我公众号,大家可以关注下。
image