一、分析报错
线上服务器崩溃,报错信息为:数据库连接失败,而此时数据库是正在运行的
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 常规的业务字段 FROM 表 WHERE 某索引列=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性能瓶颈
- CPU:CPU饱和时一般发生在:数据装入内存、从磁盘上读数据的时候、执行复杂的SQL查询时
- IO:磁盘IO瓶颈发生在查询的数据量远大于内存时
- 服务器硬件的性能瓶颈:硬盘、影响读写速度
解决方式
- 使用show full processlist查看数据库连接占用情况
- 对连接时长较长的连接进行分析,KILL掉该连接
- 查看服务器监控和MYSQL监控,分析服务器CPU、内存、磁盘IO,分析MYSQL性能
- 对SQL进行优化,比如索引优化
参考博客:
https://zhuanlan.zhihu.com/p/639445619
https://blog.csdn.net/cold_Blooder/article/details/110493200