加入收藏 | 设为首页 | 会员中心 | 我要投稿 甘孜站长网 (https://www.0836zz.com.cn/)- 运维、物联设备、数据计算、智能推荐、云管理!
当前位置: 首页 > 站长资讯 > 动态 > 正文

慢查询竟把系统搞崩了

发布时间:2021-04-06 15:03:32 所属栏目:动态 来源:互联网
导读:慢查询请求流程 案发现场 在去年双十一晚,我突然收到产品经理的催魂电话并告知:整个网站的页面一直在转菊花,无法显示数据,吓得我立马掏出电脑。 登录服务器后竟发现服务内存占用率接近 100%,CPU 长期负荷高,我迅速地检查是否代码中出现死循环、大对象

慢查询请求流程

案发现场

在去年双十一晚,我突然收到产品经理的“催魂电话”并告知:整个网站的页面一直在转菊花,无法显示数据,吓得我立马掏出电脑。

登录服务器后竟发现服务内存占用率接近 100%,CPU 长期负荷高,我迅速地检查是否代码中出现死循环、大对象内存泄露等问题,但经过排查发现代码是正常。

接着使用 jstatck pid 命令把线程堆栈信息 dump 出来,发现很多业务线程均处于 BLOCKED 状态,同时也用 jstat -gcutil 观察到 FULL GC 相当频繁。分析 dump 文件的内容及代码,发现是线程无法获取数据库连接,大量处于等待状态。

随后使用 show processlist 命令发现某个 SQL 查询耗时接近 10s 多,查询的表数据量约在 1500W 左右。

我迫不及待地分析了慢 SQL select * from t_order where merchant_id= 1349865679 limit 0 10; 从表面看起来似乎用到了索引,可是为什么扫描到行还是这么多呢?

我就去看看表结构,期望能从中找到点有价值的东西,通过 show index from t_order;后发现以下有用的信息:从上述结果中看到 merchant_id 索引的离散程度还算大,它的 Cardinality 值接近于 PRIMARY 的值,说明是比较正常的。

既然 merchant_id 索引没问题,那么猜想就是使用姿势不对的问题,我再通过 explain select * from t_order WHERE merchant_id= 1349865679 limit 0,10; 分析运行的SQL,发现确实索引没生效。

从上述图可发现,用户的请求在服务器等待数秒后才向数据库发起执行命令,而当时双十一活动火爆,请求量高,导致数据库连接耗尽,大量请求阻塞在服务器上,同时系统不断地创建 TCP 连接,这些连接直至整个请求结束后才会释放、销毁。因此,当堆积大量请求无法及时处理时,则出现服务无法响应,进一步恶化为资源挂占。

2、对象在堆内存无法回收,导致内存不足

相信大家知道,每个用户发出请求、执行逻辑时都需分配 JVM 内存,当前面的请求线程处于阻塞时,后面又越来越多新请求不断申请内存分配,但旧请求中的对象无法回收并释放内存,最终导致内存暴涨、系统响应缓存,进一步演化为系统奔溃,整个请求过程如下:

(编辑:甘孜站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读