目录
- 背景
- 原因分析
- 一、innodb_buffer_pool_size作用
- 二、查看当前配置的pool_size:
- 三、performance schema内存占用量分析
- 四、排查mysql为当前session会话分配的内存
- 查看session级别的buffer和cache占用内存大小。
- 查看当前活跃的连接数
- 五、排查当前临时表占用内存情况
- 查看tmp_table_size临时表配置的内存大小:
- 补充知识点一:临时表
- 查看当前是否有临时表产生
- 补充知识点二:Mysql内存管理模块:
- 六、问题总结和解决思路
背景
生产环境mysql 5.7内存占用超过90%以上,且一直下不来。截图如下:
原因分析
1、确定mysql具体的占用内存大小,通过命令:cat /proc/Mysql进程ID/status查看
命令执行后的结果比较多。
看到此处有必要延申一个知识点。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。
查看当前活跃的连接数
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}_序列号组成,因此不同会话可以创建同名的临时表。
查看当前是否有临时表产生
show global status like '%tmp%'
发现频繁使用了临时表,并且出现了因内存临时表不够而使用到磁盘临时表。由于临时表占用的内存具体大小可能无法准确计算得出(因为使用完会回收,但是肯定存在当前未被回收情况)。
补充知识点二:Mysql内存管理模块:
MySQL的内存分配使用了系统glibc,而glibc本身的内存分配算法存在缺陷,导致内存释放不完全,产生内存碎片。可以通过gdb命令手动回收内存碎片:
gdb --BATch --pid ‘pidof mysqld’ --ex 'call malloc_trim(0)';
但是在生产环境这个操作应该谨慎使用。
此外,将MySQL的内存分配机制修改为jemalloc,可以更好的释放内存。
六、问题总结和解决思路
总结一下MySQL内存使用率高且不释放的应对方法:
- 继续加大内存(如果参数调无可调时选择);
- 修改减小innodb_buffer_pool_size参数(牺牲一定innodb性能);
- 排查消耗内存的慢SQL,及时优化;
- 检查相关session参数是否设置合理,比如join_buffer_size、query_cache_size是否设置过大;
- 使用gdb回收内存碎片(生产环境谨慎操作):gdb --batch --pid ‘pidof mysqld’ --ex 'call malloc_trim(0)';
- 对MySQL进程配置jemalloc内存管理模块;
- 配置读写分离,将读操作应用到从库,减少对主库的影响;
以上就是MySQL内存使用率高且不释放问题排查与总结的详细内容,更多关于MySQL内存使用率高且不释放的资料请关注编程网(www.lsjlt.com)其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容- Java 中对象数组的定义及使用方式有哪些?(Java对象数组定义与用法有哪些)
- Java ClassLoader 的使用方法究竟是什么?(java classloader的使用方法是什么)
- Java 中 Bimap 的适用场景具体有哪些?(Bimap在Java中的适用场景有哪些)
- Java 和 Golang 在性能方面有哪些差异?(Java与Golang的性能差异)
- Java 中带参方法和无参方法的差异究竟体现在哪些方面?(java有参和无参的区别是什么)
- 如何在 Java 中创建 Date 对象?(java怎么创建date对象)
- 如何利用 Java Milo 开展网络编程?(如何使用Java Milo进行网络编程)
- 如何高效使用Redis客户端进行故障排查
- 如何使用 getresources 获取文件系统资源?(getresources如何获取文件系统资源)
- 如何利用 Java 的多线程提升效率?(Java的多线程如何提高效率 )