线上MySQL挂了,我做了这几件事情立即恢复

createh52周前 (03-02)技术教程2

给客户做的一个项目上线后数据库挂了,这次轻敌大意了。

去年年底交付的一个项目,今年2月份的某天客户突然打电话过来,说他们的小程序响应特别的慢,页面加载不出来。我尝试了多次确实打不开或者响应极其缓慢,看来不是个例现象,询问客户最近有做什么事情,客户说他们做了一个活动,这几天用户量上来了。

典型的用户量一上来服务就出现性能问题,我挂掉电话开始排查定位问题。

一、线上配置

为了方便大家一起和我复盘这次事故,我尽可能的提供更多一些详细的信息,我给客户整体的部署方案都是上云的,网络拓扑如下图所示:

相关配置如下:

云产品

配置

说明

SLB

简约型

负载均衡

ECS

2C4G

6台做一个负载均衡

Redis

2G

主从标准版

MySQL

2C4G

基础版 ESSD PL1 云盘100G

这套方案属于省钱版,整体下来算上促销活动一年也就1万多块钱。

二、定位解决问题

出了问题后第一时间我怀疑是部署服务的ECS出问题了,登录到阿里云控制台上发现6台服务器的各项指标都很平稳,CPU、内存都很健康,均在60%水位线以下,只是流量大了点。

这个时候我又去看了一下SLB的访问日志,看看接口的响应情况

* | SELECT status , count(1) FROM log where status > 204 GROUP BY status order by count(1) desc;

查询结果大致如下:

code

count

499

1454

504

42

401

35

408

8

发现有大量的499错误码,显然服务端此时的响应整体比较慢。可是服务器的负载、内存都很正常,那什么响应慢呢?我赶紧去查看数据库,发现数据库的CPU早就已经被打满了,持续了十几分钟了。。。

到这里我们已经定位到了是数据库出挂了,那么接下来就是要定位到具体数据库什么地方出问题了。

MySQL出现了性能问题,根据目前的场景以及客户反馈的情况我判断可能有以下几种可能:

  1. 访问量突然变大导致数据库顶不住;
  2. 慢查询、大结果集查询把数据库拖死了;
  3. 有长事务;

但是当时的数据库连接数并不高,才用了不到50%,说明连接是够用的,这点也是可以理解的,因为我给数据库连接池配置的最大链接数是200,6台算下来吃满也才1200连接数,而且看上图中MySQL的内存利用率才50%左右,但是CPU早就100%了,说明要计算的东西多,数据结果集不大。

到这里,基本上可以判断是有慢查询了

虽然上面说了一大堆,但是排查思路上也就是几分钟的事情,紧接着就去看MySQL的慢查询日志:

发现有好多这样的日志,需要解析的行数18万多,返回的结果就20条,显然这种SQL一看就没走索引,看具体业务是一个排行榜相关的业务,因为前期没有数据量,直接查询的表,也没做索引设计,结果导致数据库CPU直接100%!

找到了具体的问题点,接下来就是修复了,具体措施如下:

1、排行榜接口降级,不走具体查询逻辑,返回固定的数据;

2、扩容MySQL到4C8G,重启MySQL,优先恢复访问;

3、修复错误数据;

4、解决排行榜的问题,因为排行榜实时性要求不高,我们可以不用每次都查询业务表,而且单独做一张排行榜表,业务数据有变更时候异步计算排名数据,同时加入缓存机制;

5、性能优化,根据SLB日志查看所有的接口调用排名,根据频率高低、耗时长短来挨个走查是否存在性能问题,数据库是否有效命中索引,表数据量大不大,是否需要增加缓存等等全方位系统优化;

最终花了2天时间做了一次系统大的优化,优化上线后系统性能明显好转,最直接的体现就是顺利的扛住了客户的活动流量,即使在业务高峰期,服务器、数据库的压力都明显降低,并且稳定运行至今,最终也得到了客户的认可(响应及时、快速解决问题)。

三、MySQL索引常见问题总结

在 MySQL 中,会引发性能问题的查询,基本上都是查询没有有效命中索引所导致,而没有有效命中索引具体又分为两种情况:

1、SQL语句没写好,没有按照创建的索引规则来写

2、索引设计的不好

SQL语句没写好导致索引失效是大家比较常见的一种情况,日常工作中也比较容易犯错:

  1. 左模糊查询:like %xxx;
  2. 含有关键字 or、<>、!=、not in、not exist等等;
  3. 函数计算 where DATE(create_time) = '2023-04-25';
  4. 索引列参与运算 where num + 1 = 10;
  5. 类型不一致,例如name字段是varchar类型,查询语句为where name = 18;
  6. 联合索引没遵循最左匹配原则。

索引设计的不好也是SQL调优的重灾区,常见的有:

  1. 能走覆盖索引的没走覆盖索引;
  2. 索引区分度设计不好,导致mysql认为走索引还不如走全表扫描;
  3. 没有很好的利用索引下推机制;
  4. 一张表设计了太多的索引;
  5. 索引上的字段有null值;

以上只是总结了一些常见的错误,实际开发中由于业务的复杂性,很多SQL大家并不能一眼就能看出来到底有没有走索引,有没有走合适的索引,强烈建议大家在写SQL时候优先使用EXPLAIN来查看SQL语句的执行计划来综合评估,从而写出最佳SQL。

你还知道日常开发中关于数据库方面哪些容易犯的错误?欢迎评论区留言讨论~

感谢各位点赞、收藏、转发、关注,持续为您分享优质内容!

相关文章

jar不能双击运行(命令行可以执行)的解决方案

Java应用程序jar文件可以由 JVM(Java虚拟机)直接执行,只要操作系统安装了JVM便可以运行作为Java应用程序的jar文件,其跨平台特性使得很多工具软件都用jar方式来部署分发。可是,很多...

# Win10/WIN11 打不开【本地组策略编辑器】解决方案

#java学不进去怎么办## Win10/WIN11 打不开【本地组策略编辑器】解决方案段子手168## 问题描述:当在 WIN + R 打开【运行】输入:gpedit.msc 打开【本地组策略编辑器...

《我的世界》Win10没反应打不开怎么办?

《我的世界》中有很多使用Win10或者Win8系统的玩家们打不开游戏,该如何解决?这里带来玩家“SuiYa”分享的解决方法,有相同问题的玩家们可以进行参考。解决办法:PS:未必对所有玩家有效。首先打开...

Java的finally真的保险吗?程序员必知的五个失效场景

你以为的"保险柜",也有打不开的时候程序员圈子里流传着一句话:“finally是代码的保险柜,永远会执行”。但真相是——这个"保险柜"的钥匙,有时候会被偷偷藏起来。举个:你点了外卖,外卖小哥说"一定送...

学习Java最应该关注的20个网站,建议收藏

学习Java是一个漫长的过程,除了学习课程之外,我们可以多关注一些网站,包括项目平台、开发者社区、教程分享网站等等。这些网站和上面的资源,可以帮助我们在学习的过程中,更好的吸收和消化所学知识。推荐收藏...

小白如何系统的学习Java?内行人给出这样的建议

随着现代经济济和科技的发展,中国Java编程开发语言行业已经步入了一个高速发展的时代。大家有目共睹了Java编程语言发展的迅猛,每年的Java人才缺口人数都高达百万以上。在我们的工作中、学习中、生活中...