KingbaseES 数据库CPU使用率过高问题与解决

发布时间 2023-09-19 19:22:46作者: KINGBASE研究院

前言

本文介绍生产环境中CPU使用率高的常见原因,以及在CPU使用率高问题上的可能解决措施。

本文主要内容:
关于用于识别高CPU使用率的工具,例如kwr报告中DB CPU指标、kmonitor和sys_stat_statements。
确定CPU使用率高的根本原因。
使用 Explain Analyze查看执行计划、连接池和vacuum表解决CPU使用率过高的问题。

识别CPU使用率高的方法

1.kwr报告中DB CPU指标
DB CPU指标可作为一段时间内CPU使用率的依据。
kwr报告提供CPU使用率过高时的有关sql耗时。

2.kmonitor
kmonitor监控工具中资源使用率项可监控cpu使用率。并提供邮件、短信告警功能。
注:如果操作系统部署了nmon工具,也可以查看一段时间内cpu使用率,或在操作系统使用top命令查看cpu使用情况。

3.sys_stat_statements
sys_stat_statements扩展可识别占用cpu时间的查询。

查询sql的总cpu消耗时间
select c.rolname,b.datname,a.total_parse_time+a.total_plan_time+a.total_exec_time as total_time,a.* from sys_stat_statements a,sys_database b,sys_authid c where a.userid=c.oid and a.dbid=b.oid order by a.total_exec_time desc limit 5;

查询sql平均执行时间
SELECT userid::regrole, dbid, query, mean_exec_time 
FROM sys_stat_statements 
ORDER BY mean_exec_time 
DESC LIMIT 5;    

查询sql总执行时间
SELECT userid::regrole, dbid, query 
FROM sys_stat_statements 
ORDER BY total_exec_time 
DESC LIMIT 5;   

CPU消耗较高的原因可能有

1.长时间运行的事务
长事务可能导致CPU使用率过高。

查询运行时间最长的连接:
SELECT pid, usename, datname, query, now() - xact_start as duration
FROM sys_stat_activity
WHERE pid <> sys_backend_pid() and state IN ('idle in transaction', 'active')
ORDER BY duration DESC;

2.数据库总连接数
数据库的大量连接也可能会导致CPU和内存使用率增加。

以下查询提供按状态排序的连接数信息:
SELECT state, count(*)  
FROM  sys_stat_activity   
WHERE pid <> sys_backend_pid()  
GROUP BY 1 ORDER BY 1;   

3.低效的sql
kwr报告中 Top SQL By Elapsed Time,Top SQL By CPU Time可以查询消耗高cpu的sql语句,再通过explain analyze语法分析该sql执行计划从而优化sql。

4.硬件性能低
有的业务系统执行大批量sql导致服务器cpu使用率高有时是正常现象,并不一定都是慢sql导致,这种情况往往因为服务器硬件资源有限。

解决CPU使用率较高的问题

1.使用 Explain Analyze
使用explain语法进一步查看sql的真实执行计划并进行优化。有关explain命令的详细信息,可在ksql客户端使用\h explain查看。

2.使用连接池
如果存在大量空闲连接或大量使用CPU的连接,请考虑使用连接池程序控制总连接数和空闲连接时长。

3.终止长时间运行的事务
可以考虑和应用人员协商终止长时间运行的事务释放内存和cpu资源。

如要终止会话的PID,需要使用以下查询有关PID:
SELECT pid, usename, datname, query, now() - xact_start as duration 
FROM sys_stat_activity  
WHERE pid <> sys_backend_pid() and state IN ('idle in transaction', 'active') 
ORDER BY duration DESC;   

获得会话的PID后,可以使用以下查询进行终止:
SELECT sys_terminate_backend(pid);
注:如果此终止方式失败,则需要在操作系统调用gdb命令终止会话连接。

4.更新表的统计信息
使表的统计信息保持最新状态有助于提高查询性能,监视是否正在执行常规vacuum。

以下查询可识别需要vacuum的表:
select schemaname,relname,n_dead_tup,n_live_tup,last_vacuum,last_analyze,last_autovacuum,last_autoanalyze 
from sys_stat_all_tables where n_live_tup > 0;

其中字段last_autovacuum和last_autoanalyze提供上次自动vacuum或分析表的日期和时间,如果未定期vacuum表,请执行以下步骤来优化自动vacuum。

临时解决方案是对表执行手动vacuum
vacuum analyze <table_name>;