Mysql慢SQL堆积导致数据库连接池占满

一、分析报错

线上服务器崩溃,报错信息为:数据库连接失败,而此时数据库是正在运行的

Error querying database. Cause:
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to
obtain JDBC Connection; nested exception is
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is
not available, request timed out after 30001ms.

二、查看数据库连接占用情况

show full PROCESSLIST

三、SQL分析

EXPLAIN SELECT 常规的业务字段 FROMWHERE 某索引列=xx AND is_deleted =xx 

在这里插入图片描述

数据库表总量近七千万,删除标志的查询条件没有索引,扫描了五百万的数据。

四、数据库配置、SpringBoot项目配置关键信息

🍔留个坑,有时间再另外写一篇~

五、慢SQL为什么会导致系统崩溃

连接占满(我是这种情况)

用show full PROCESSLIST 发现连接数已经占满了,而且连接占用的时间都比较长,就算是一个简单的sql也等待了很长时间还是没有执行完,所以导致无法获取连接的情况。
其中有一条语句重复堆积了80来个慢SQL,查询时间为50秒~600秒不等,且有一半在500-600秒的。
用kill 进程ID 把运行较慢的SQL杀掉,再重启数据库和应用服务,连接就正常了。

大量IO导致

MYSQL的数据是以文件的心事存储在磁盘上的,查询时会从磁盘将数据读到内存,再进行处理,此时会产生IO。
MYSQL的INNODB存储引擎在设计的时候已经想到了IO会影响数据库的性能,于是设计了缓冲池。当MYSQL进行查询的时候,首选将磁盘读到的页放在缓冲层中。下一次再读相同页时,首先判断该页是否在缓冲池中,若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则读取磁盘上的页。
问题的关键在于:缓冲池的大小直接影响着数据库的整体性能,查询7千万的数据时,缓冲池的作用就微乎其微了,还是会产生大量的IO。

在这里插入图片描述

六、MYSQL性能瓶颈

  1. CPU:CPU饱和时一般发生在:数据装入内存、从磁盘上读数据的时候、执行复杂的SQL查询时
  2. IO:磁盘IO瓶颈发生在查询的数据量远大于内存时
  3. 服务器硬件的性能瓶颈:硬盘、影响读写速度

解决方式

  1. 使用show full processlist查看数据库连接占用情况
  2. 对连接时长较长的连接进行分析,KILL掉该连接
  3. 查看服务器监控和MYSQL监控,分析服务器CPU、内存、磁盘IO,分析MYSQL性能
  4. 对SQL进行优化,比如索引优化

参考博客:
https://zhuanlan.zhihu.com/p/639445619
https://blog.csdn.net/cold_Blooder/article/details/110493200

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值