全部产品
Search
文档中心

:PolarDB MySQL版CPU使用率高

更新时间:Jun 07, 2026

CPU作为数据库的核心资源,是日常运维中重点关注的对象。CPU的过度使用将导致应用响应时间(RT)的增加、业务的卡顿,甚至更严重的情况可能导致数据库实例挂起(hang死)、发生高可用(HA)问题,从而严重影响现网任务。因此,正常情况下,CPU的监控应设定安全水位,一旦超出安全水位应及时进行处理,以避免引发不可预期的严重后果。

现网业务中的CPU使用率

随着业务的增长,数据库集群的规格可能已经不能满足业务流量的上涨需求。此时由于流量的不断增长,数据库集群的使用率逐渐提升,CPU使用率也逐渐升高。如果从性能曲线进行观察,必然存在某个指标(如QPS/IOPS)呈上涨趋势,与CPU使用率上涨趋势相似。

此时,如果CPU出现瓶颈,基本可以断定数据库集群规格已不足以支撑当前的业务流量,此时最好对数据库集群增加只读节点或者扩容集群规格。

说明

如果数据库集群出现无法连接或正在执行的DML语句失败,请检查当前数据库集群规格的CPU资源是否已不足以支撑当前业务场景。如果确认CPU资源不足,请及时对集群进行扩容操作以确保系统稳定运行。

  • 如果大部分业务场景都是读请求,可以通过增加节点,进行集群横向扩容,以分流读请求。

  • 如果大部分业务场景都是写请求,此时增加只读节点不会对性能起到提升作用,需要对集群规格进行手动扩容,例如:由4C规格变更为8C规格。

非预期内CPU使用率增长

导致CPU使用率非预期增长的情况比较复杂,本文主要针对比较常见的几个现象进行说明,包括慢查询、活跃线程高、内核配置不合理以及系统BUG。

慢查询

正常情况下,CPU使用率的增长,一般是由于SQL语句不合理,产生了慢查询,同时活跃线程堆积导致CPU使用率过高。但是一定要区分清楚,是由于慢查询导致的CPU使用率高,还是由于其他资源满载导致查询变慢导致的CPU使用率高。

您可以在PolarDB控制台诊断与优化 > 慢SQL菜单中,查看慢查询情况。如果慢查询中有数据,就需要对这些数据进行分析。如果在慢日志明细页签中,扫描行远远大于返回行数,则说明是慢查询导致的CPU使用率过高。

说明

此处主要针对TP类查询进行分析,需要排除掉count类查询,一些AP类查询的扫描行数确实很大。

TP类查询业务的读写数据量都非常小,如果某个查询的扫描数据量非常大,那么大概率是由于索引缺失导致。例如下述查询语句在慢查询列表中显示扫描数据量为1万+,但返回数据为1条,那么很明显在name列上有索引缺失的情况。

SELECT * FROM table1 WHERE name='testname';

那么可以通过下述语句确认在name列上是否有索引。

SHOW index FROM table1;
  • 如果name列上没有索引,可以通过下述语句添加索引列,消除此类大数据量扫描导致的慢查询。

    ALTER TABLE table1 ADD KEY ix_name (name);
  • 如果name列上有索引,可以通过下述语句查看SQL语句的执行计划,确认是否使用了正确的索引。

    EXPLAIN SELECT * FROM table1 WHERE name='testname';

    如果发现name列有索引,但没有被使用,有可能是出现了统计信息不准确导致生成了错误的执行计划。可以通过下述语句重新生成表上的统计信息用以纠正错误计划。

    ANALYZE TABLE table1;

    执行完成后,再通过下述语句确认是否使用了正确的索引。

    EXPLAIN SELECT * FROM table1 WHERE name='testname';

活跃线程高

活跃线程高一定会带来CPU使用率的增长。抽象来说,MySQL实现中,每一个CPU只能在同一时间内处理一个请求。假设是16C规格的集群,最多只能同时处理16个请求。但是要注意,这里的请求指的是内核层面,而非应用的并发层面。您可以在PolarDB控制台诊断与优化 > 一键诊断 > 会话管理菜单中,查看会话情况。

如果排除掉慢查询导致的请求无法正常处理,活跃线程堆积一般都是由于现网业务流量增长造成的。通过查看性能曲线,如果整体流量以及请求趋势和活跃线程的堆积趋势一致,那么说明集群资源已经达到上限,此时需要通过对数据库集群增加只读节点或者扩容集群规格来解决。

需要注意的是,在活跃线程达到临界点时,可能在CPU层面开始产生争抢,内核中会产生大量的mutex排他锁,此时性能曲线表现特征为高CPU使用率、高活跃线程、低IO或低QPS。另外一种情况是突然的业务洪峰,建立连接速度非常快,也可能在CPU层面产生大量争抢,从而导致请求堆积。此类问题一般可以通过开启集群的Thread Pool特性进行流控缓解。如果活跃线程有所缓解,同时还要注意应用侧是否已经产生了业务堆积,如果CPU负载较高同时活跃线程依然高居不下,此时则同样要考虑是不是对集群进行扩容操作。

另有一种情况是前端连接风暴导致集群流量瞬间堆积,此时流量属于异常流量,一般出现在流量数据被爬虫拉取数据的场景下。此时可以通过SQL限流的方式进行请求拒绝,具体操作请参见会话管理

内核配置不合理

自建MySQL的参数是通用场景下的标准配置,对于个别业务可能不太适用,需要进行微调。有些问题在业务上线初期数据量较少的情况下不会触发,但是随着时间的推移,业务数据量增大,在特定条件下有些问题就会暴露出来。

比较常见的问题会出现内存使用争抢。在MySQL体系中,内存主要作为数据缓存使用,这意味着数据需要不断地迭代,最常用是buffer poolinnodb_adaptive_hash_index内存区域。整个数据库系统的缓存区域,是数据交换最为频繁的位置,如果内存不足和内存页争抢,则会出现各种异常的堆积和慢查询。最典型的表现是数据库突然CPU上涨打满,并且出现慢查询。经过排查后发现该问题并非索引缺失,这个时候就有可能是内存系统发生了问题。

例如:在进行truncate table操作时,MySQL要遍历buffer pooltruncate表的数据页全部驱逐。此时大规格的集群中,如果innodb_buffer_pool_instances配置为1并且并发相对较高的情况下,就有可能出现争抢问题。这个问题在业务上线初期就可以发现,一般来说可以将innodb_buffer_pool_instances的取值与CPU核数对齐,将buffer pool进行分桶,就可以规避此类问题。

另外一种场景是innodb_adaptive_hash_index出现争抢,比较明显的表现是执行下述命令时会出现大量的hash0hash.cc等待。

SHOW ENGINE innodb STATUS;

在AHI显示段中,会出现明显的数据倾斜。

insert 0, delete mark 0, delete 0
Hash table size 25499819, node heap has 20720 buffer(s)
Hash table size 25499819, node heap has 25111 buffer(s)
Hash table size 25499819, node heap has 23884 buffer(s)
Hash table size 25499819, node heap has 16835 buffer(s)
Hash table size 25499819, node heap has 23132 buffer(s)
Hash table size 25499819, node heap has 189284 buffer(s)
Hash table size 25499819, node heap has 38864 buffer(s)
Hash table size 25499819, node heap has 49094 buffer(s)
5469.32 hash searches/s, 5282.36 non-hash searches/s

此类问题可以将innodb_adaptive_hash_index参数关闭,也就是直接弃用AHI特性,已有数据表明在混合读写的场景下AHI也有可能带来负面的性能影响,关闭后对整体业务的影响不是很大。

系统BUG

系统BUG是相对少见的问题,例如早期出现的进程死锁以及因表上统计信息置为0而导致的全表扫描等。随着产品的快速迭代,因系统BUG引发的CPU问题相对较少。然而,在排查此类问题时,涉及很多的内核层面信息,您自行处理可能有一定的难度。建议联系我们以获取技术支持进行问题排查。