生产数据库服务器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使用率居高不下的重要原因。

复盘总结

  1. 复用其他同学的代码也务必把逻辑都仔细过一遍;

  2. 方法参数一定要校验,特别是非空判断,DAO层的方法更加要谨慎仔细;

  3. 谨慎使用JPA,必须熟悉掌握JPA的底层原理,这次出问题的findAll()方法换成findAllById()的话就不会出现这种情况了;

 

posted @ 2023-05-18 01:06  road2master  阅读(78)  评论(0)    收藏  举报