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

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

内容简介:前段时间收到运维反馈,线上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慢查询问题排查过程


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

查看所有标签

猜你喜欢:

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

在你身边,为你设计

在你身边,为你设计

腾讯公司用户研究与体验设计部 / 电子工业出版社 / 2013-1 / 69.00元

设计属于所有人,也意在为所有人使用,这既是设计的价值,也是设计的责任。本书内容包括:设计理念、设计方法、用户研究、体验设计、设计流程和工具,以及团队成长与管理等方面的知识与经验分享。一起来看看 《在你身边,为你设计》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具