问题:
某数据库持续报警,系统负载过高,达到160左右。
![](https://img.haomeiwen.com/i13005604/1ff36036d3d12bc0.png)
初步分析:
1)查看监控
数据库并发 QPS 15000/s ,连接数保持2800左右。
sys load 70%,us cpu 20%-----→ 很奇怪,sys load 负载高,说明函数使用过多,上下文切换? io 资源不够用?
2)数据库参数
innodb_thread_concurrency=0 --→ 不做限制? 但是cpu 核数是固定的,业务并发又高。肯定有问题
测试该参数设置为1(限制同时只能跑一个线程)后,30s 左右,系统可能会恢复正常。
然后再设置为0,过一会又出问题。 --→ 更说明这个参数设置不合理
3) show engine innodb status\G
看到很多线程在 opening table、sending data、 copy to tmp table,sorting result 状态
设置 table_open_cache=1000,tmp_table_size=64M,不起作用。
4)相关sql语句
语句1:
相关sql 的表索引都是单字段索引。走了索引,每个sql 还需要扫描几十条记录。
加了复合索引后,系统负载立马恢复正常。 问题解决了?
为了验证确实是这个索引导致的。 于是决定把索引删了!!!!!
这一删,发现并发太高,根本删不掉,反而系统负载又飚起来,比之前还高。
不停的告警中!!!!!
语句2:
如下图,app_id 索引已经有了,每个sql还需要扫描8000多行数据。
查看表结构,发现有一个大字段类型text
同时慢日志不停的打印这个sql。 ---→ 联想到上面的sql 状态都是 sending data、 copy to tmp table 是有原因的。
![](https://img.haomeiwen.com/i13005604/1ec063db5370fc4f.png)
赶紧联系开发,修改逻辑,sql 查询时,不返回该大字段。
但是系统负载依旧。。。。。没有缓解!!!!
语句3:
发现在processlist 中有498条SQL 在执行,很普通的sql,正常应该执行很快,但是已经执行了1h 左右。
sending data、 copy to tmp table,sorting result 状态.
于是KILL , 但是kill 杀不掉。系统负载进一步加剧。。。。。。。
5)、联系业务,重启DB。
killed 状态的线程 停不了, 只能kill mysql 进程。
重启mysql 后,截止第二天12点,系统负载一直保持正常状态。(如下图)
![](https://img.haomeiwen.com/i13005604/32d881ee04e92934.png)
总结:
1、高并发系统, innodb_thread_concurrency=0 不做限制,设置不合理,必须降低io 的并发。
2、索引不合适,需要及时调整
3、大字段类型,不能频繁的出现查询SQL中,尤其是高并发的系统。
4、高并发也不正常,业务自己需要完善。QPS 15000/s ??? 。 下面是 业务改版后的趋势图:
![](https://img.haomeiwen.com/i13005604/097611c7cc7abcdf.png)
![](https://img.haomeiwen.com/i13005604/4d2cfd5f8634fca8.png)
网友评论