暗藏玄机的MySQL查询超时问题
-
线上有个定时任务,这个任务需要查询一个表几天范围内的一些数据做一些处理,每隔十分钟执行一次,直至成功。通过日志发现,从凌晨5:26分开始到5:56任务执行了三次,三次都因为SQL查询超时而执行失败,而诡异的是,任务到凌晨6:00多就执行成功了。每天都是凌晨五点多失败,凌晨六点执行成功。总结来说就是MySQL查询超时问题。我以为三分钟可以解决完成,但事实上并且如此。 看到超时SQL,大多数人第一反应就是这个SQL没有走索引,我也不例外,我当时的第一反应就是这条SQL没有走索引。SQL里面有两个日期参数,这两个起始日期是某种商品的可交易时间区间,相隔三到五天,我取了17天的时间间隔的保守值,Explain了一下这条SQL。 根据Explain结果,我当时的推断是:这条SQL肯定走了索引,如果没有走索引,那六点多钟的查询肯定也会超时,因为这个表的数据是千万级别的。为了验证这一推断,我找DBA帮我导出了一下凌晨5点到早上7点关于这个表的慢SQL,DBA告诉我那个时间段没有关于这个表的慢SQL。 这也进一步验证了我说推断:这条SQL走了索引,只是在五点多的时候因为一些神秘原因导致了超时。接下来,需要做的就是找出这个神秘的原因。 按照以往的经验,我认为有这几点因素会导致查询超时MySQL资源竞争、数据库备份、网络。 MySQL资源竞争:首先,我通过监控系统查看了那段时间MySQL的运行情况,连接数和CPU负载等指标都非常正常。所以,因为MySQL负载导致超时首先就可以被排除。 数据库备份:首先备份锁表不会锁这么久,这个任务是前前后后半个小时都执行失败了;其次我们是备份的从库,并不是备份的主库;最后,我们的备份任务都不是凌晨五点执行的。所以,因为备份导致超时可以排除了。 网络:是不是网络波动的原因呢?我找运维同学帮忙看了一下执行任务的那台机器那段时间的网络情况,非常平缓没有丝毫问题,机房也没有出现什么网络抖动的情况。再者,如果是网络问题,肯定会影响其他任务和业务的,事实上,从监控系统中查看其他业务并没有什么异常。所以,因为网络波动导致超时也可以排除了。 当自己的设想被一个个推翻,在我突然要放弃的时候,我突然发现SQL日志记录里面的时区都是标准时区的,而我那个任务执行的时候是北京时间,要知道标准时区和北京时区是差了8个小时的! 从日志上面可以看到,查询的日期区间从2020年9月到2021年4月,时间跨度7个月。MySQL成本计算的时候认为区间太大,走索引还不如直接扫描全表,最终没有走索引扫描了1800W条数据。 说好的时间区间最多七天呢?怎么变成了七个月?赶紧定位代码,定位发现底层在取时间区间时,调了一个RPC接口,这个接口预期返回的时间区间只有几天,结果返回了七个月的时间区间。这段逻辑是18年上线的。 于是联系提供这个RPC接口的相关人员,通过查找验证确定这是底层数据的问题,应该返回几天结果返回了几个月。最后修复了相关数据,增加了相应的校验和监控,重新发布系统,这个存在了两年的BUG也就得以解决了。
西南地区IT社群(QQ)
- 云南
- 【昆明网页设计交流吧】243627302
- 【昆明nodejs交流吧】 243626749
- 【VUE】838405306
- 【云南程序员总群】343606807
- 【昆明UI设计】104031254
- 【云南软件外包】15547313
- 贵州
- 【PHP/java源码/站长交流群】55692114
- 四川
- 【成都Java/JavaWeb交流】86669225
- 【vaScript+PHP+MySql】116270060
- 【UI设计/设计交流学习群】135794928
- 重庆
- 【诺基亚 JAVA游戏博物馆】 559479780
- 【PHP,Java,Python,C++接单】 442103442
- 西藏