当前位置: 首页 > news >正文

MySQL内存使用率高且不释放问题排查与总结

背景

生产环境mysql 5.7内存占用超过90%以上,且一直下不来。截图如下:

原因分析

1、确定mysql具体的占用内存大小,通过命令:cat /proc/Mysql进程ID/status查看

命令执行后的结果比较多(其他参数的含义想了解可参考这个博客:Linux 进程的 status 注解。_rssanon-CSDN博客),重点看VmRSS参数发现使用了120G左右。

看到此处有必要延申一个知识点。innodb_buffer_pool_size

一、innodb_buffer_pool_size作用

        InnoDB存储引擎是MySQL中最常用的存储引擎之一,它使用内存缓存池(buffer pool)来缓存表中的数据和索引等信息。通过调整innodb_buffer_pool_size参数的大小,可以控制InnoDB存储引擎能够利用的内存空间,进而影响其缓存的数据量和索引数量

  innodb_buffer_pool_size设置的值较大时,InnoDB存储引擎能够缓存更多的数据和索引,从而减少磁盘I/O的次数,提高数据库的访问速度和性能。相反,如果缓存池设置过小,可能会导致频繁的磁盘I/O操作,影响数据库性能。

        一般为物理内存的60%-70%。

二、查看当前配置的pool_size:

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

发现结果是64G(配置文件也可查看),这里就发现问题:实际使用的内存量比配置的量多出了60G左右。

暂且把64G当成正常占用多出来的当成异常占用分析。

三、performance schema内存占用量分析

show engine performance_schema status;

查看结果中的最后一行。发现占用了200多M。

四、排查MySQL为当前session会话分配的内存

查看session级别的buffer和cache占用内存大小。

show variables where variable_name in ('binlog_cache_size','join_buffer_size','read_buffer_size','read_rnd_buffer_size','sort_buffer_size')

结果如下:

总共加起来接近800M。

里边每个值的含义和作用参考:MySQL session相关的内存设置_mysql为当前session会话分配的内存-CSDN博客

查看当前活跃的连接数

SELECT * FROM information_schema.processlist WHERE command != 'Sleep';

结果显示差不多只有9个,加入每个都分配了全量的会话内存,则差不多就是9G。(实际分配了多少需要根据当前会话执行的SQL判断,比如有无使用到排序、有没有使用join等)。上边的算完顶多才10G,还有50多G的消耗,也就意味着还有其他的占用。

五、排查当前临时表占用内存情况

查看tmp_table_size临时表配置的内存大小:

线程级别参数,实际限制从 tmp_table_size 和 max_heap_table_size 两个变量的的值中取较小值。

show variables where variable_name in ('tmp_table_size','max_heap_table_size')

 补充知识点一:临时表

        如果内存中的临时表超出限制,MySQL自动将其转换为磁盘上的MyISAM表。如果要执行许多 GROUP BY查询,可以增加tmp_table_size的值(或如有必要,也可以使用max_heap_table_size)。

  执行计划中Extra字段包含有“Using temporary” 时会产生临时表。

        MySQL中临时表主要有两类,包括外部临时表和内部临时表。外部临时表是通过语句create temporary table...创建的临时表,临时表只在本会话有效,会话断开后,临时表数据会自动清理。内部临时表主要有两类,一类是information_schema中临时表,另一类是会话执行查询时,如果执行计划中包含有“Using temporary”时,会产生临时表。内部临时表与外部临时表的一个区别在于,我们看不到内部临时表的表结构定义文件frm。而外部临时表的表定义文件frm,一般是以#sql{进程id}_{线程id}_序列号组成,因此不同会话可以创建同名的临时表。

         什么时候创建临时表:mysql中什么时候用临时表-mysql教程-PHP中文网

查看当前是否有临时表产生

show global status like '%tmp%'

发现频繁使用了临时表,并且出现了因内存临时表不够而使用到磁盘临时表。由于临时表占用的内存具体大小可能无法准确计算得出(因为使用完会回收,但是肯定存在当前未被回收情况)。

补充知识点二:Mysql内存管理模块:

         MySQL的内存分配使用了系统glibc,而glibc本身的内存分配算法存在缺陷,导致内存释放不完全,产生内存碎片。可以通过gdb命令手动回收内存碎片:

gdb --batch --pid ‘pidof mysqld’ --ex 'call malloc_trim(0)';

但是在生产环境这个操作应该谨慎使用。

此外,将MySQL的内存分配机制修改为jemalloc,可以更好的释放内存。关于glibc和jemalloc机制对MySQL数据库内存回收的影响可以参考这篇文章:https://mp.weixin.qq.com/s/iUvi0xPtKng08fNu_5VWDg

六、问题总结和解决思路

总结一下MySQL内存使用率高且不释放的应对方法:

  1. 继续加大内存(如果参数调无可调时选择);
  2. 修改减小innodb_buffer_pool_size参数(牺牲一定innodb性能);
  3. 排查消耗内存的慢SQL,及时优化;
  4. 检查相关session参数是否设置合理,比如join_buffer_size、query_cache_size是否设置过大;
  5. 使用gdb回收内存碎片(生产环境谨慎操作):gdb --batch --pid ‘pidof mysqld’ --ex 'call malloc_trim(0)';
  6. 对MySQL进程配置jemalloc内存管理模块;
  7. 配置读写分离,将读操作应用到从库,减少对主库的影响;

相关文章:

  • 黑马点评项目难点-动态代理,sychronized,@Transactional失效的情况
  • JAVA小知识31:多线程篇2
  • 1-Pandas是什么
  • Perl 语言开发(四):条件语句
  • python学习-基础1
  • JSON字符串中获取一个指定字段的值
  • 第1章 人工智能的基础概念与应用导论
  • C++ 定长队列的实现
  • 【博士每天一篇文献-综述】A survey on few-shot class-incremental learning
  • 【已解决】: fatal error: cuda_runtime_api.h: No such file or directory
  • 行业洞察 | 2024应用程序安全领域现状报告
  • Dataweave2 语法教程
  • 【前端项目笔记】8 订单管理
  • python笔记
  • 详细分析Oracle修改默认的时间格式(四种方式)
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • 5、React组件事件详解
  • JavaScript学习总结——原型
  • JS学习笔记——闭包
  • leetcode-27. Remove Element
  • Vue.js-Day01
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 搞机器学习要哪些技能
  • 好的网址,关于.net 4.0 ,vs 2010
  • 基于axios的vue插件,让http请求更简单
  • 面试遇到的一些题
  • 区块链技术特点之去中心化特性
  • 如何合理的规划jvm性能调优
  • 白色的风信子
  • 1.Ext JS 建立web开发工程
  • 带你开发类似Pokemon Go的AR游戏
  • ​【已解决】npm install​卡主不动的情况
  • ​水经微图Web1.5.0版即将上线
  • #### go map 底层结构 ####
  • #APPINVENTOR学习记录
  • #LLM入门|Prompt#3.3_存储_Memory
  • #微信小程序:微信小程序常见的配置传值
  • $().each和$.each的区别
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (剑指Offer)面试题34:丑数
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (原创)可支持最大高度的NestedScrollView
  • (转)Linux下编译安装log4cxx
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .cfg\.dat\.mak(持续补充)
  • .form文件_SSM框架文件上传篇
  • .NET Core 中插件式开发实现
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net分布式压力测试工具(Beetle.DT)
  • .NET中GET与SET的用法
  • .NET中使用Redis (二)