CPU使用率高问题定位及处理方法
指标异常说明(影响)
系统CPU使用率:指的是整个系统CPU运行时间占总CPU时间的百分比。
CPU使用率分别有用户态CPU时间占比和内核态CPU时间占比:
- 用户态:是用户程序运行时的状态。
- 内核态:是操作系统的管理程序运行时的状态,包含系统调用,内核线程和中断。
当CPU打满的时候,会使业务变慢。
问题排查思路
引起CPU爆满的原因一般分为三种:
- 活跃会话陡增
- ECS底层资源争抢(非独享型实例)
- 慢SQL被大量执行
三种可能性有对应的排查方法,如下图所示:
排查方法
- 活跃连接数陡增排查方法
活跃连接数陡增会有两个比较典型的现象:内核态CPU时间占比>20%,活跃连接数会有陡增的情况,可以结合起来一起看。
- ECS资源争抢(非独享型实例)
在内核态CPU时间占比>20%的场景中,还有一种比较罕见的情况:ECS资源争抢,这种情况发生在非独享型(包括:通用型、通用增强型等)实例中。
通常情况下,RDS for PostgreSQL实例上的内核态CPU都是低于10%的,当内核态CPU时间占比>10%以上就要警惕是否是由ECS资源争抢导致的CPU爆满,可以联系客服确认是否发生资源争抢。
- 导致CPU消耗陡增的SQL排查方法
华为云RDS for PostgreSQL数据库有慢SQL日志,可以通过这个日志,定位到当时比较耗时的SQL来进一步做分析。但通常问题发生时,整个系统都处于停滞状态,所有SQL都慢下来,当时记录的慢SQL可能非常多,并不容易找到目标。
这里推荐几种追查慢SQL的方法,除了慢SQL以外,还有一些简单执行时间很短的SQL,在某些情况下(例如:在事务中循环执行、大量的并发执行)也会导致CPU消耗的陡增。
追查慢SQL方法如下:
- 通过pg_stat_statements插件定位导致CPU消耗增高的SQL,详细使用请参考使用pg_stat_statements插件。
- 通过pg_stat_activity视图查看当前长时间执行的SQL。
SELECT *, (now() - backend_start) AS proc_duration, (now() - xact_start) AS xact_duration, (now() - query_start) AS query_duration, (now() - state_change) AS state_duration FROM pg_stat_activity WHERE pid<>pg_backend_pid() ORDER BY state_duration DESC limit 10;
- 通过查询pg_stat_user_tables,排查数据库中存在的大量的全表扫描的表以及对应的SQL。
select * from pg_stat_user_tables order by seq_tup_read desc, seq_scan desc limit 10;
- 结合pg_stat_statements或者pg_stat_activity,排查是否存在对应的慢SQL。
前提需要安装pg_stat_statements插件。
结合pg_stat_statements排查慢SQL:
select * from pg_stat_statements where query like '%tablename%' order by shared_blks_hit + shared_blks_read desc;
结合pg_stat_activity排查慢SQL:
select *, (now() - backend_start) AS proc_duration, (now() - xact_start) AS xact_duration, (now() - query_start) AS query_duration, (now() - state_change) AS state_duration from pg_stat_activity where pid<>pg_backend_pid() and query like '%tablename%' ORDER BY state_duration DESC;
这些慢SQL通常是由于缺少查询对应的索引,导致过多的buffer读,从而消耗大量CPU。