引言
在生产环境中,MySQL作为一个关键的数据库组件,其性能对整个系统的稳定性至关重要。然而,有时候我们可能会遇到MySQL CPU使用率过高的问题,这可能导致系统性能下降,应用页面访问减慢,甚至影响到用户体验。本文将详细介绍如何排查和解决MySQL CPU过高的问题,帮助您迅速恢复正常的数据库性能。
首先我们要明白什么是CPU使用率:
CPU使用率是指在单位时间内CPU处于非空闲状态的时间比,反映了CPU的繁忙程度。某个进程的CPU使用率就是这个进程在一段时间内占用的CPU时间占总的时间的百分比。比如在双核CPU某个开启多线程的进程1s内占用了CPU0 0.6s, CPU1 0.9s, 那么它的占用率是150%。这里不深入阐述,网上文章很多。
CPU占用过高原因分析
CPU 占用过高常见原因:
- 服务器硬件问题
- 内存溢出
- 高并发业务中业务设计不合理导致
- 数据库对象设计不合理
- 表索引设计不合理
- 数据库锁导致,如行锁冲突、行锁等待、锁超时、死锁等
- 系统架构没有缓存中间件
- 读写分离配置不合理
- 未合理升级改造为集群环境
- MySQL 系统参数设置不合理
- 问题 SQL 导致
SQL 问题导致 CPU 使用率过高是最常见的现象,比如 group by、order by、join 等,这些很大程度影响 SQL 执行效率,从而占用大量的系统资源。
说了这么多常见原因,其实总结一句话来说就是现有系统的现有配置下的现有环境提供不了所需要的数据查询、分析、执行能力,针对这个问题,首先我们要发现问题的所在,就是说我们要准确的定位问题,然后针对问题进行优化,再考虑其他升级改造的事情。
检查MySQL运行情况
可以看到CPU使用率非常高,内存使用较低,可以排除不是内存影响的。而且内存资源还有很大空间。
因此要解决问题,可以从两方面入手:
- 优化Mysql参数配置,发挥服务器硬件性能,通过合适的参数配置提升Mysql性能(以空间换时间,见效快,成本高)
- 找到问题原因,优化问题sql、添加合理的索引、引入缓存等
方案一:MySQL配置参数优化
查看服务器资源
查看服务器内存:
[java@localhost ~]$ grep MemTotal /proc/meminfo
MemTotal: 266419264 kB // 约256G
查看服务器CPU个数:
[java@localhost ~]$ lscpu
架构: aarch64
CPU 运行模式: 64-bit
字节序: Little Endian
CPU: 64
在线 CPU 列表: 0-63
每个核的线程数: 1
每个座的核数: 32
座: 2
NUMA 节点: 2
厂商 ID: HiSilicon
型号: 0
型号名称: Kunpeng-920
步进: 0x1
Frequency boost: disabled
CPU 最大 MHz: 2600.0000
CPU 最小 MHz: 200.0000
BogoMIPS: 200.00
L1d 缓存: 4 MiB
L1i 缓存: 4 MiB
L2 缓存: 32 MiB
L3 缓存: 64 MiB
NUMA 节点0 CPU: 0-31
NUMA 节点1 CPU: 32-63
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected
Vulnerability Meltdown: Not affected
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1: Mitigation; __user pointer sanitization
Vulnerability Spectre v2: Not affected
Vulnerability Srbds: Not affected
Vulnerability Tsx async abort: Not affected
标记: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm ssbs
可以看到服务器有两个物理CPU,每个物理CPU有32个内核数,即总共64个逻辑CPU数。
一般情况下,逻辑cpu=物理CPU个数×每颗核数
观察MySQL状态
MySQL的运行状态是我们排查性能问题的第一步。通过查看全局状态变量,我们可以获取系统的整体运行情况。以下是一些关键的状态变量和信息:
- Threads_running 和 Threads_connected
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
</