生产数据库服务器CPU使用率居高不下问题排查
现象与恢复
Prometheus监控报警数据库服务器CPU一直维持在100%以上,没有丝毫下降。
重启消费MQ消息的服务,以及MySQL实例后,CPU使用率断崖式下降,系统访问正常了。
原因分析
第一时间,判断是慢查询所致。查看阿里云SQL分析工具,总扫描行数这个指标有异常,达到了亿级。并发现大量的相同的SQL一直在执行,
最终定位于JPA的findAll()方法,参数是持久层对象PO,由于只使用了PO的一个属性(ID)作为查询条件【其实这里正确的使用应该是findAllById(),而非findAll()方法,因为条件只有一个并且是ID】,又由于封装findAll()的方法没判空,刚好查询出来的数据ID都为空,自动生成的SQL如下:
select * from table_name;
生成的SQL不带where子句,很简单粗暴查全表。导致业务逻辑的下一条SQL
SELECT * FROM table_name WHERE id IN (id1, id2, id3, ...);
根据全表数据的ID筛选过多的数据,致命的是这段逻辑是消费Canal发到Kafka的消息,canal监听的是核心服务的主表,数据量大,还做了分库分表,平均每天增量数据能达到 5~7k 条,所以这也是CPU使用率居高不下的重要原因。
复盘总结
-
复用其他同学的代码也务必把逻辑都仔细过一遍;
-
方法参数一定要校验,特别是非空判断,DAO层的方法更加要谨慎仔细;
-