解析MySQL生产环境CPU使用率过高的排查与解决方案

news2024/9/26 21:57:46

引言

在生产环境中,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的运行状态是我们排查性能问题的第一步。通过查看全局状态变量,我们可以获取系统的整体运行情况。以下是一些关键的状态变量和信息:

  1. Threads_running 和 Threads_connected
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Threads_connected';

Threads_running 表示当前正在执行的线程数量。
Threads_connected 表示当前已连接到MySQL的线程数量。
如果 Threads_running 较高,而 Threads_connected 较低,可能表明存在某些长时间运行的查询,或者可能是由于连接池配置不当导致连接被频繁创建和销毁。

  1. InnoDB 相关状态
SHOW ENGINE INNODB STATUS;

查看InnoDB引擎状态,关注以下信息:

Innodb_row_lock_current_waits:表示当前正在等待的行锁数量。
Innodb_deadlocks:显示发生的死锁次数。
高的行锁等待和死锁次数可能表明业务逻辑或查询需要优化,或者存在并发访问冲突。

  1. Key_reads 和 Key_writes
SHOW GLOBAL STATUS LIKE 'Key_reads';
SHOW GLOBAL STATUS LIKE 'Key_writes';

Key_reads:表示从磁盘读取索引块的次数。
Key_writes:表示向磁盘写入索引块的次数。
高的 Key_reads 可能暗示着索引未能完全放入内存中,需要调整 key_buffer_size 参数。而频繁的 Key_writes 可能表明索引的写入操作较为频繁,需要考虑索引的优化。

  1. Created_tmp_disk_tables
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';

表示在磁盘上创建的临时表的数量。过多的磁盘临时表可能表明某些查询需要优化,或者 tmp_table_size 参数设置过小。

  1. Uptime
SHOW STATUS LIKE 'Uptime';

表示MySQL服务的运行时间。如果CPU问题突然发生,检查这个值,看是否与问题的时间点相关。

  1. 其他关键状态变量

浏览MySQL官方文档以获取更多有关全局状态变量的信息,根据具体情况添加监控和分析。

通过这些状态变量,我们可以初步了解MySQL的整体运行情况,从而有针对性地继续深入排查问题。在分析状态时,可以使用各种监控工具,如pt-mysql-summary或MySQL Enterprise Monitor,以更方便地查看和理解MySQL的状态信息。

Mysql参数设置

数据库属于IO密集型的应用程序,其主职责就是数据的管理及存储工作。而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个 IO是在毫秒级别,二者相差3个数量级。所以,要优化数据库,首先第一步需要优化的就是IO,尽可能将磁盘IO转化为内存IO。

SELECT version(); // 版本:8.0.30

 // 索引块的缓冲区大小,增加它可得到更好处理的索引
show global variables like 'key_buffer_size';  // 默认值:8M

set global key_buffer_size=1024*1024*64

show global variables like 'max_allowed_packet'; // 默认值:64M

show global variables like 'table_open_cache'; // 默认值:4000

set global table_open_cache=16000

// sort_buffer_size是MySql执行排序使用的缓冲大小
show global variables like 'sort_buffer_size'; // 默认值:256KB

set global sort_buffer_size=1024*1024*16

show global variables like 'net_buffer_length'; // 默认值:16KB

 //read_buffer_size 是MySql读入缓冲区大小。
show global variables like 'read_buffer_size'; // 默认值:128KB

set global read_buffer_size=1024*1024*8

 // tmp_table_size是MySql的heap (堆积)表缓冲大小
show global variables like 'tmp_table_size'; // 默认值:16M

set global tmp_table_size=1024*1024*128

 // read_rnd_buffer_size 是MySql的随机读缓冲区大小
show global variables like 'read_rnd_buffer_size'; // 默认值:256KB

set global read_rnd_buffer_size=1024*1024*4

// thread_cache_size可以重新利用保存在缓存中线程的数量     
show global variables like 'thread_cache_size'; // 默认值:8

set global thread_cache_size=64



// MySql的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,
// 当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySql会为每个连接提供连接缓冲区,就会开销越多的内存
show global variables like 'max_connections'; // 最多连接数, 默认:151

set global max_connections=5000;

show global variables like 'max_connect_errors'; // 默认值:100

set global max_connect_errors=1000;

show global variables like 'open_files_limit'; // 默认值:1M

show global variables like 'innodb_data_file_path';    

// InnoDB
// 对InnoDB表性能影响最大的一个参数。InnoDB缓冲池用于缓存数据和索引,对于读取频繁的表,适当调整缓冲池大小可以显著提升性能。// innodb_buffer_pool_size设置为系统中Mysql可用内存的70%左右。这确保了大部分数据和索引都可以在内存中缓存,减少磁盘I/O操作。
show global variables like 'innodb_buffer_pool_size'; // 默认值:128M

set global innodb_buffer_pool_size=1024*1024*1024*32 //32G

//InnoDB事务日志文件大小
 show global variables like 'innodb_log_file_size';

// InnoDB存储引擎的事务日志所使用的缓冲区
show global variables like 'innodb_log_buffer_size';  // 默认值:16M

set global innodb_log_buffer_size=1024*1024*128

show global variables like 'sync_binlog';

set global sync_binlog=1000

可根据自己服务器性能动态调整,但重启后会失效,最好同时修改my.cnf配置文件:

通过参数调优后的MySQL状态:
在这里插入图片描述

参数参考:

  • MySQL性能优化之参数配置

  • mysql配置参数调优

方案二:SQL问题分析定位解决

MySQL的查询分析是排查性能问题的关键步骤。通过检查慢查询日志和使用性能分析工具,我们可以找到潜在的性能瓶颈。

  1. 启用慢查询日志
    首先,确保MySQL的慢查询日志功能已启用。在MySQL配置文件中添加以下配置:
slow_query_log = 1
slow_query_log_file = /usr/local/mysql/slowlog/slow-query.log
long_query_time = 1

slow_query_log 启用慢查询日志。
slow_query_log_file 设置慢查询日志文件路径。
long_query_time 定义慢查询的时间阈值(单位:秒),这里设置为1秒。

或者使用MySQL客户端:

 
-- 启动慢查询日志
set global slow_query_log='ON';

-- 设置慢查询存储文件地址
set global slow_query_log_file='/usr/local/mysql/slowlog/slow-query.log';
 
-- 设置储存sql条件,sql 执行时间高于0.001秒存入日志文件
set global long_query_time=0.001;

-- 开启 记录没有使用索引查询语句
set global log-queries-not-using-indexes = on
  1. 分析慢查询日志
    使用以下命令查看慢查询日志中的内容:
tail -f /usr/local/mysql/slowlog/slow-query.log

或者使用MySQL客户端:

SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';

通过检查慢查询日志,识别执行时间长的查询。注意关注查询的执行计划,以便理解MySQL是如何处理这些查询的。

  1. 使用慢查询分析工具
    使用工具如pt-query-digest来分析慢查询日志:
pt-query-digest /path/to/slow-query.log

该工具能够生成详细的报告,包括执行时间最长的查询、查询频率、索引使用情况等信息。通过这些信息,您可以确定哪些查询需要优化,以提高其性能。

  1. Explain命令
    对于特定的查询,使用EXPLAIN命令来查看其执行计划:
EXPLAIN SELECT * FROM your_table WHERE your_condition;

EXPLAIN命令将显示MySQL执行查询时的执行计划,包括使用的索引、访问表的方式等。通过分析执行计划,您可以了解查询的性能瓶颈,并进行相应的优化。

  1. 优化查询
    根据慢查询日志和执行计划的分析结果,对性能较差的查询进行优化。可能的优化方式包括:
  • 优化查询语句,避免全表扫描。
  • 优化 SQL,降低 SQL 复杂度,降低 MySQL 执行成本。
  • 确保查询涉及的列都有合适的索引。
  • 考虑分表、分区表等策略,以减少单表的数据量。

通过以上步骤,您将能够更好地理解哪些查询对系统性能有负面影响,并有针对性地进行优化,提高整体性能。

结论

通过以上步骤,您应该能够定位和解决MySQL CPU使用率过高的问题。请注意,每个生产环境都是独特的,可能需要根据实际情况进行适当调整。保持监控和定期优化是确保MySQL性能稳定的关键。希望这篇文章对您解决MySQL性能问题提供了帮助。如果有任何问题或建议,请随时留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1414556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构与算法——队列

概述 计算机科学中,queue 是以顺序的方式维护的一组数据集合,在一端添加数据,从另一端移除数据。添加的一端称为尾,移除的一端称为头。 功能 插入offer(value : E) : boolean  取值并移除poll() : E  取值peek() : E  判断…

Redis案例-微信抢红包

Redis案例-微信抢红包 1、业务描述 ​ 微信红包,一个人能发红包,红包的分发规则,红包能被几个人抢,超过24小时没有人领取自动退回原账户,红包详情页面有每个人的抢红包记录,包括金额大小和时间&#xff0…

统计学-R语言-7.3

文章目录 前言总体方差的检验一个总体方差的检验两个总体方差比的检验 非参数检验总体分布的检验正态性检验的图示法Shapiro-Wilk和K-S正态性检验总体位置参数的检验 练习 前言 本篇文章继续对总体方差的检验进行介绍。 总体方差的检验 一个总体方差的检验 在生产和生活的许多…

使用BootStrapBlazor组件搭建Bootstarp风格的Winform界面

项目地址https://gitee.com/zhang_jie_sc/my-blazor-winforms 1.安装Bootstrap.Blazor.Templates 模板 在power shell中输入dotnet new install Bootstrap.Blazor.Templates::7.6.1,安装7.6.1是因为版本8以后就要强制使用net8.0了,很多语法不一样&…

了解WPF控件:ToggleButton和Separator常用属性与用法(十三)

掌握WPF控件:熟练ToggleButton和Separator常用属性(十三) ToggleButton 一个按钮类UI元素,它的特点是拥有两种状态:选中(Checked)和未选中(Unchecked)。当用户单击Togg…

pve8.1 安装、创建centos7虚拟机及配置

之前创建虚拟机centos7时,硬盘分配太大了,做成模板后无法进行修改了,安装完pve8.1后,强迫症犯了重新创建一下顺便记录一下配置过程。由于目前centos7还是生产用的比较多的版本所以本次还是安装centos7.9版本。 一、下载镜像 下载…

使用 CDC MinIO 汇入端为 CockroachDB 保持持久数据

CockroachDB 数据库迅速崭露头角,作为一个坚韧且可扩展的分布式 SQL 数据库。它从其昆虫名字的坚持不懈中汲取灵感,即使面对硬件故障,CockroachDB 也能保证高可用性。其分布式架构横跨多个节点,类似于其昆虫原型的适应性。 凭借强…

dos攻击与ddos攻击的区别

①DOS攻击: DOS:中文名称是拒绝服务,一切能引起DOS行为的攻击都被称为dos攻击。该攻击的效果是使得计算机或网络无法提供正常的服务。常见的DOS攻击有针对计算机网络带宽和连通性的攻击。 DOS是单机于单机之间的攻击。 DOS攻击的原理&#…

JavaScript学习-原型和原型链

原型和原型链 示例代码 //创建一个Person类 class Person {constructor(name) {this.name name;}drink() {console.log(喝水);} } //创建一个Teacher类,继承Person class Teacher extends Person {constructor(name, subject) {super(name);this.subject subjec…

详细解读vcruntime140_1.dll修复的手段,如何快速解决vcruntime140_1.dll丢失问题

当出现“无法找到vcruntime140_1.dll”或程序“未能正常启动”时,这通常指示系统中缺失了一个关键文件:vcruntime140_1.dll。作为Visual C Redistributable组件的一部分,这个小文件在很多用Visual Studio编译的C程序运行时发挥着重要作用。解…

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空,返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…

P1042 [NOIP2003 普及组] 乒乓球 Java版最简单题解!

为什么说最简单,因为本人就是一个算法小白,只学过一点数据结构,打算备战蓝桥杯的,网上说备战蓝桥杯就去刷洛谷,早有听闻洛谷很难,今天一看算是真的被打醒了,对于小白是真的太难了。(;༎ຶД༎ຶ…

在Idea中使用git查看历史版本

idea查git历史 背景查看步骤总结 背景 有好几次同事到我电脑用idea查看git管理的历史记录,每次都说我的idea看不了历史版本,叫我到他电脑上去看,很晕,为什么,原来是我自己把显示历史文件的视图覆盖了,下面我们来一起学…

Python open函数

在Python编程中,open()函数是一个重要的文件操作函数,用于打开文件并进行读取、写入、追加等操作。本文将深入探讨open()函数的用法、语法、文件模式、示例代码,并探讨其在实际编程中的应用场景。 什么是open()函数? open()函数…

【阻塞队列】阻塞队列的模拟实现及在生产者和消费者模型上的应用

文章目录 📄前言一. 阻塞队列初了解🍆1. 什么是阻塞队列?🍅2. 为什么使用阻塞队列?🥦3. Java标准库中阻塞队列的实现 二. 阻塞队列的模拟实现🍚1. 实现普通队列🍥2. 实现队列的阻塞功…

Python.五.文件

1.文件读取的操作 1.文件的打开 open(name,mode,encoding) name:是要打开目标文件名的字符串,可以包含文件所在的具体路径 mode:设置打开文件的模式:只读 r 、写入 w 、追加 a encoding:编码格式 UTF-8 fopen("C:/test.txt"…

XSS_Labs靶场通关笔记

每一关的方法不唯一;可以结合源码进行分析后构造payload; 通关技巧(四步): 1.输入内容看源码变化; 2.找到内容插入点; 3.测试是否有过滤; 4.构造payload绕过 第一关 构造paylo…

怎么获取二维码的链接?二维码转链接只需3步

怎么从二维码中提取内容呢?现在很多内容都会用二维码方式来存储,但是有些场景下二维码是无法使用的时候,想要查看二维码中的内容,就需要分解二维码成链接后使用。那么二维码分解成链接具体该怎么做呢?今天就将在线二维…

Hammer.js中文教程

一、什么是hammer.js hammerJS是一个开源的,轻量级的触屏设备javascript手势库,它可以在不需要依赖其他东西的情况下识别触摸,鼠标事件。允许同时监听多个手势、自定义识别器,也可以识别滑动方向。 优点: 为移动端网…

[已解决]504 Gateway Time-out 网关超时

文章目录 问题:504 Gateway Time-out 504 Gateway Time-out 网关超时思路解决 问题:504 Gateway Time-out 504 Gateway Time-out 网关超时 思路 网上的常规思路是修改nginx配置文件,增加请求执行时间,试过没有用 keepalive_timeout 600; fastcgi_con…