Mysql占用CPU过高如何优化

Mysql占用CPU过高如何优化,第1张

CPU占用过高诊断思路

mpstat -P ALL 1,查看cpu使用情况,主要消耗在sys即os系统调用上

perf top,cpu主要消耗在_spin_lock

生成perf report查看详细情况

CPU主要消耗在mutex争用上,说明有锁热点。

采用pt-pmp跟踪mysqld执行情况,热点主要集中在mem_heap_alloc和mem_heap_free上。

Pstack提供更详细的API调用栈

Innodb在读取数据记录时的API路径为

row_search_for_mysql --》row_vers_build_for_consistent_read --》mem_heap_create_block_func --》mem_area_alloc --》malloc --》  _L_unlock_10151 --》__lll_unlock_wait_private

row_vers_build_for_consistent_read会陷入一个死循环,跳出条件是该条记录不需要快照读或者已经从undo中找出对应的快照版本,每次循环都会调用mem_heap_alloc/free。

而该表的记录更改很频繁,导致其undo history list比较长,搜索快照版本的代价更大,就会频繁的申请和释放堆内存

Linux原生的内存库函数为ptmalloc,malloc/free调用过多时很容易产生锁热点。

当多条 SQL 并发执行时,会最终触发os层面的spinlock,导致上述情形。

解决方案

将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。

修改my.cnf,添加如下参数并重启

[mysqld_safe]malloc-lib=tcmalloc

上周五早上7点执行的 *** 作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。

以下是修改前后cpu使用率对比

MySQL是一款常用的关系型数据库管理系统,它的 CPU 平均使用率指的是 MySQL 进程在某一时间段内 CPU 的平均使用率。通常情况下,MySQL CPU 平均使用率应该保持在合理的范围内,过高的 CPU 使用率可能会导致 MySQL 性能下降。

如果你想要查看 MySQL CPU 平均使用率,可以使用以下方法:

使用 MySQL 的状态监控工具:MySQL 提供了一些状态监控工具,如 mysqladmin、mysqltuner 等,这些工具可以帮助你查看 MySQL 的 CPU 使用情况。

Linux上MySQL优化提升性能,可以优化关闭NUMA特性如下:

这些其实都源于CPU最新的技术:节能模式。 *** 作系统和CPU硬件配合,系统不繁忙的时候,为了节约电能和降低温度,它会将CPU降频。

为了保证MySQL能够充分利用CPU的资源,建议设置CPU为最大性能模式。这个设置可以在BIOS和 *** 作系统中设置,当然,在BIOS中设置该选项更好,更彻底。

然后我们看看内存方面,我们有哪些可以优化的。

i)我们先看看numa

非一致存储访问结构(NUMA:Non-UniformMemoryAccess)也是最新的内存管理技术。它和对称多处理器结构(SMP:SymmetricMulti-Processor)是对应的。

我们可以直观的看到:SMP访问内存的都是代价都是一样的但是在NUMA架构下,本地内存的访问和非本地内存的访问代价是不一样的。对应的根据这个特性, *** 作系统上,我们可以设置进程的内存分配方式。目前支持的方式包括:

--interleave=nodes

--membind=nodes

--cpunodebind=nodes

--physcpubind=cpus

--localalloc

--preferred=node

简而言之,就是说,你可以指定内存在本地分配,在某几个CPU节点分配或者轮询分配。除非是设置为--interleave=nodes轮询分配方式,即内存可以在任意NUMA节点上分配这种方式以外。其他的方式就算其他NUMA节点上还有内存剩余,Linux也不会把剩余的内存分配给这个进程,而是采用SWAP的方式来获得内存。

所以最简单的方法,还是关闭掉这个特性。

关闭特性的方法,分别有:可以从BIOS, *** 作系统,启动进程时临时关闭这个特性。

a)由于各种BIOS类型的区别,如何关闭NUMA千差万别,我们这里就不具体展示怎么设置了。

b)在 *** 作系统中关闭,可以直接在/etc/grub.conf的kernel行最后添加numa=off,如下所示:

kernel/vmlinuz-2.6.32-220.el6.x86_64roroot=/dev/mapper/VolGroup-rootrd_NO_LUKS.UTF-8rd_LVM_LV=VolGroup/rootrd_NO_MDquietSYSFONT=latarcyrheb-sun16rhgbcrashkernel=autord_LVM_LV=VolGroup/swaprhgbcrashkernel=autoquietKEYBOARDTYPE=pcKEYTABLE=usrd_NO_DMnuma=off

另外可以设置vm.zone_reclaim_mode=0尽量回收内存。

c)启动MySQL的时候,关闭NUMA特性:

numactl--interleave=allmysqld

当然,最好的方式是在BIOS中关闭。

ii)我们再看看vm.swappiness。

vm.swappiness是 *** 作系统控制物理内存交换出去的策略。它允许的值是一个百分比的值,最小为0,最大运行100,该值默认为60。vm.swappiness设置为0表示尽量少swap,100表示尽量将inactive的内存页交换出去。

具体的说:当内存基本用满的时候,系统会根据这个参数来判断是把内存中很少用到的inactive内存交换出去,还是释放数据的cache。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/6137604.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-16
下一篇 2023-03-16

发表评论

登录后才能评论

评论列表(0条)

保存