【RDS for PostgreSQL】CPU满问题原因及定位思路

举报
大象数据库 发表于 2021/11/05 15:01:21 2021/11/05
【摘要】 基本概念系统CPU使用率: 指的是整个系统CPU运行时间占总CPU时间的百分比。CPU使用率分别有用户态CPU时间占比和内核态CPU时间占比:用户态: 是用户程序运行时的状态。内核态: 是操作系统的管理程序运行时的状态,包含系统调用,内核线程和中断。某个进程的CPU使用率: 就是某个进程在一段时间内占用的CPU时间占总的CPU时间的百分比。活跃连接数: 指状态为activity的数据库连接...

基本概念

系统CPU使用率: 指的是整个系统CPU运行时间占总CPU时间的百分比。

CPU使用率分别有用户态CPU时间占比内核态CPU时间占比

  • 用户态: 是用户程序运行时的状态。
  • 内核态: 是操作系统的管理程序运行时的状态,包含系统调用,内核线程和中断。

某个进程的CPU使用率: 就是某个进程在一段时间内占用的CPU时间占总的CPU时间的百分比。

活跃连接数: 指状态为activity的数据库连接。

CPU核心数与活跃连接数的关系: 正常情况下,合理的活跃会话数量应当是当前CPU核数的2~3倍,例如实例规格为2核4GB时,活跃会话数应当维持在4~6个,此时的CPU使用效率最高。

问题排查思路

引起CPU爆满的原因一般分为三种:活跃会话徒增、ECS底层资源争抢(非独享型实例)、CPU消耗陡增的SQL被大量执行。三种可能性有对应的排查方法,如下图所示。

CPU爆满分析--原因导向.png

排查方法

排查步骤

第一步:确认实例规格(CPU核心数内存规格类型

第二步:查看内核态CPU时间占比

第三步:查看活跃连接数

第四步:判断实例规格类型,若为独享型则跳转至第八步,否则下一步

第五步:若内核态CPU时间占比 > 40%,执行下一步,否则跳转至第八步

第六步:与华为云ECS人员确认是否发生资源抢占情况,若发生资源抢占请其协助解决,然后执行下一步,否则跳转至第八步

第七步:等待资源抢占情况解决后,观察CPU满问题是否得以解决,是则结束,否则进入下一步

第八步:查看近24小时或者近7天的活跃连接数监控图,判断是否有陡增情况发生,是则下一步,否则跳转至第十二步

第九步:与业务沟通交流最近的业务变化,识别活跃连接数陡增是否由业务变化引入,是则下一步,否则跳转至第十二步

第十步:分析当前活跃连接数是否超出实例规格承受范围,是则下一步,否则跳转至第十二步

第十一步:建议先回退业务变更,并提高数据库实例规格,待实例规格提高后再进行业务变更,结束

第十二步:排查导致CPU消耗陡增的SQL

第十三步:优先结束导致CPU消耗陡增的SQL的进程使业务恢复

第十四步:观察CPU满问题是否得以解决,是则进入下一步,否则跳转至第十六步

第十五步:对第十二步中获取到的导致CPU消耗陡增的SQL进行分析、优化,彻底消除CPU爆满的隐患,结束

第十六步:联系华为云客服,进行更深层次的问题定位。

活跃连接数陡增

活跃连接数陡增会有两个比较典型的现象:内核态CPU时间占比>20%,活跃连接数会有陡增的情况,可以结合起来一起看。

查看内核态CPU时间占比

监控平台

通过监控平台中的内核态CPU时间占比监控项进行查看,选择近1小时查看当前的内核态CPU时间占比,如下图所示。

image-20211027201251082.png

内核态CPU时间占比高于20%,此时说明可能存在大量的系统调用或者中断,通常对应的是系统中存在大量正在工作的进程。

说明:

当活跃连接数超出了实例规格的承受能力,系统不停的切换CPU中运行的进程,而内核程序切换CPU让其在不同的地址空间上操作,导致内核态CPU时间占比升高。

查看活跃连接数

监控平台

通过监控平台中的活跃连接数监控项进行查看,选择近24小时近7天查看最近一段时间的活跃连接数的情况,确认是否存在陡增现象以及陡增时间点,如下图所示。

image-20211027200444543.png

另外活跃连接数陡增与陡增时间点可以通过客户业务进一步加以确认。

小结

结合 内核态CPU时间占比>20% 以及 活跃连接数存在陡增 现象两个现象基本可以确定CPU的爆满的原因为:活跃连接数陡增。此时可以从业务侧进行排查,确认陡增活跃连接数是否是业务所需,若为业务所需建议通过提高实例规格来解决问题,否的话则从业务上优化活跃连接数陡增问题。

ECS资源争抢(非独享型实例)

内核态CPU时间占比>20% 的场景中,还有一种比较罕见的情况:ECS资源争抢,这种情况发生在非独享型(包括:通用型、通用增强型等)实例中。

内核态CPU时间占比>40%以上就要警惕是否是由ECS资源争抢导致的CPU爆满,可以联系ECS员工进行确认是否发生资源争抢。

排查导致CPU消耗陡增的SQL

如果已经排除了活跃连接数陡增ECS资源争抢两种可能性,那么可能是此时有慢SQL被大量执行。华为云RDS for PostgreSQL数据库有慢SQL日志,可以通过这个日志,定位到当时比较耗时的SQL来进一步做分析。但通常问题发生时,整个系统都处于停滞状态,所有SQL都慢下来,当时记录的慢SQL可能非常多,并不容易找到目标。这里推荐几种追查慢SQL的方法。除了慢SQL以外,还有一些简单执行时间很短的SQL,在某些情况下(例如:在事务中循环执行、大量的并发执行)也会导致CPU消耗的陡增。

导致CPU消耗增高的SQL类型.png

通过以下几种方法定位到导致CPU消耗增加的SQL,可以先结束它们使业务恢复,然后再对它们进行优化。

操作行数

通过监控平台中的操作函数监控项进行查看,选择近24小时或者近7天查看最近的操作行数,如下图所示。

image-20211028185348506.png

若最近的操作行数出现陡增的现象,说明最近业务上可能出现了一些慢SQL,这些慢SQL通常是由于缺少查询对应的索引,导致过多的buffer读,从而消耗大量CPU。

pg_stat_statements

第一步

先查看当前数据库是否有安装pg_stat_statements插件,执行如下SQL:

select * from pg_extension  where extname = 'pg_stat_statements';

查询结果示例如下:

-- 未安装插件
xxxx=# select * from pg_extension  where extname = 'pg_stat_statements';
 oid | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition 
-----+---------+----------+--------------+----------------+------------+-----------+--------------
(0 rows)

-- 已安装插件
xxxx=# select * from pg_extension  where extname = 'pg_stat_statements';
  oid  |      extname       | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition 
-------+--------------------+----------+--------------+----------------+------------+-----------+--------------
 xxxxx | pg_stat_statements |    34637 |         2200 | t              | 1.7        |           | 
(1 row)

若没有安装pg_stat_statements插件,需要手动安装一下。

第二步

为了方便排查当前CPU过高问题,需要重置pg_stat_statments的计数器,执行以下SQL:

select pg_stat_reset();
select pg_stat_statements_reset();

然后等待一段时间,使pg_stat_statments能够统计到足够的信息。

第三步

获取最耗时的SQL,执行一下SQL:

select * from pg_stat_statements order by total_time desc limit 10;

此步骤获取到的SQL会长时间占用用户态CPU时间,把这些SQL取出来分析。

第四步

获取读取Buffer次数最多的SQL,执行一下SQL:

select * from pg_stat_statements order by shared_blks_hit + shared_blks_read desc limit 10;

此步骤获取到的SQL可能由于缺少查询对应的索引,导致过多的buffer读,从而消耗大量CPU。

第五步

获取执行次数最多的SQL,执行以下SQL:

select * from pg_stat_statements order by calls desc limit 10;

有些比较简单的SQL单独执行耗时较低,但是在某些情况下(例如:在事务中循环执行、大量的并发执行)也会导致CPU的消耗增高。

pg_stat_activity

查看数据库系统中当前长时间执行的SQL/事务,这些SQL/事务也可能造成CPU过高,执行以下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。

执行一下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
select * from pg_stat_statements where query like '%tablename%' order by shared_blks_hit + shared_blks_read desc;

-- 结合 pg_stat_activity
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。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。