记录一次线上Mysql慢查询问题排查过程

栏目: IT技术 · 发布时间: 5年前

内容简介:前段时间收到运维反馈,线上Mysql数据库凌晨时候出现慢查询的报警,并把原始sql发了过来:表数据量200W左右,不是很大,而且是根据主键更新。我看到sql后第一反应就是是不是数据库出问题了,每个小时都有业务,偏偏白天业务高峰时间段正常,凌晨业务量很少时候出问题,让运维先检查了数据库的状态,反馈是数据库正常。

背景

前段时间收到运维反馈,线上 Mysql 数据库凌晨时候出现慢查询的报警,并把原始 sql 发了过来:

--去除了业务含义的sql
update test_user set a=1 where id=1;

表数据量200W左右,不是很大,而且是根据主键更新。

问题排查

  1. 排查Mysql数据库

我看到sql后第一反应就是是不是数据库出问题了,每个小时都有业务,偏偏白天业务高峰时间段正常,凌晨业务量很少时候出问题,让运维先检查了数据库的状态,反馈是数据库正常。

  1. 排查业务代码(第一次)

这块业务代码比较复杂,而且是别人写的,第一次看都没看完,直接在代码里打印了各个模块执行的时间,然后上线。

  1. 排查业务代码(第二次)

第二天又出现慢查询了,我赶紧下载了线上日志,发现整个方法执行时间很长,然后发现执行时间长的代码有几行调用其他服务的代码,使用的是HttpClient,猜到了原因,应该是调用其他超时导致的。

说下系统整体流程,微信(A)回调我们的收银台服务(B),收银台更新订单信息并调用业务服务(C)。

出问题原因是:

第一次A调用B,B锁住记录行并调用C,这个时候C没有响应,导致A又发送了第二次请求。

第二次A调用B,B更新记录时候发生死锁,出现慢查询。

解决方案

  1. 收银台系统B接收回调的方法添加分布式锁,保证同一时刻同一订单只能更新一次。

  2. 收银台调用业务服务使用的是HttpClient4.4,默认超时时间60秒,这么长时间如果对方没有响应就完了,改成了5秒,超时立马返回,不影响其他业务。

HttpClient4.4版本设置超时时间代码如下:

HttpPost httpPost = new HttpPost(url);
 RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
 httpPost.setConfig(requestConfig);

上面设置了3个超时时间,含义如下:

setConnectTimeout:设置连接超时时间,单位毫秒。

setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。

setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。

最后,按照这两个方案改造上线后,系统运行正常,问题解决。

推荐阅读

如果觉得文章不错,希望可以随手转发或者”在看“哦,非常感谢哈!

关注下方公众号后回复「1024」,有惊喜哦!

记录一次线上Mysql慢查询问题排查过程


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Probability and Computing

Probability and Computing

Michael Mitzenmacher、Eli Upfal / Cambridge University Press / 2005-01-31 / USD 66.00

Assuming only an elementary background in discrete mathematics, this textbook is an excellent introduction to the probabilistic techniques and paradigms used in the development of probabilistic algori......一起来看看 《Probability and Computing》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试