原标题:MySQL内存管理,内存分配器和操作系统
导读
作者:Sveta Smirnova
翻译:郑志江
校对:徐晨亮
原文 :MySQL Memory Management, Memory Allocators and Operating System
本文涉及链接在文末展示
当用户使用任何软件(包括MySQL)碰到内存问题时,我们第一反应就是内存泄漏。正如这篇文章所示,其实并不总是这样。
这篇文章阐述一个关于内存的bug。
所有percona所支持的客户都有获得bug修复的资格,但他们也有不同的选择。比如,vip客户在软件补丁正式发布之前就可以获得hotfiix版本,高级客户甚至不需要使用percona的软件,我们也可以为他们把补丁推到上游。但对于与percona产品来说,所有支持等级都有权得到bug修复。
即便如此,这并不意味着我们会修复所有的意外情况,即使我们接受这种情况为一个有效bug。做出这样的决定的原因之一可能是这个意外情况虽然很明确是错误的,但对于percona产品本身来说确实一个产品需求
作为学习案例的一个bug
最近一个很好的案例是 PS-5312——这个bug可在上游复现并被记录在bugs.mysql.com/95065。
这个报告阐述了一种情况,当访问InnoDB的全文索引的时候会导致内存使用量增长。这种情况出现在一些全文索引的查询,内存会持续增长直到达到最大值,并且很长时间不会释放。
来自Percona工程团队的Yura Sorokin研究表明,这种情况并不属于内存泄漏范畴。
当InnoDB解析一个全文查询时,它会在fts_query_phrase_search函数中创建一个内存堆,这个堆可能增长到80M。另外,这个过程还会使用到大量非连续块(mem_block_t)进而产生的内存碎片。
在函数出口,这些内存堆会被释放。InnoDB会为其分配的每一个块做这个操作。在函数执行结束时,调用一个内存分配器库中的free()操作,比如malloc或者jemalloc。从MySQL本身来看,这都是没问题的,不存在内存泄漏。
然而,free()函数被调用时确实应该释放内存,但不需要将其返回给操作系统。如果内存分配器发现这些内存块马上还需要被用到,则会将他们保留住继续用于mysqld进程。这就解释了为什么mysqld在完成工作及释放内存都结束后还会占用大量内存。
这个在实际生产中并不是一个大问题,按道理不应该造成任何事故。但是如果你需要更快地将内存返回给操作系统,你可以尝试非传统的内存分配器,类似jemallolc。它被证明可以解决PS-5312的问题。
另一个改善内存管理的因素是cpu内核数量:在测试中,cpu核数越多,内存返回给操作系统的速度会越快。这可能是你拥有多个CPU,而其中一个可专门用作内存分配器释放内存给操作系统。
正如我们的工程师Yura Sorokin所发现的一样,下面两点阐述了InnoDB全文索引的早期实现引入了这个缺陷:
5.6版本MySQL最早对InnoDB WL全文索引功能引入的介绍:#5538: InnoDB全文搜索支持 – https://dev.mysql.com/worklog/task/?id=5538
实现WL #5538 InnoDB全文搜索支持与合并 - https://github.com/mysql/mysql-server/commit/b6169e2d944 - 也存在同样的问题问题
修复方法
我们有两种方法来修复这个问题:
1.修改InnoDB全文索引的实现
2.使用自定义内存库,例如jemalloc
这两种方法都有各自的优缺点。
方法1 :意味着我们引入了与软件上游不兼容性的风险,这可能会导致新版本中出现未知的错误。也意味着彻底重写InnoDB全文索引部分代码,这在用户们使用的GA版本中是有风险的。
方法2 则意味着我们可能会命中一些jemalloc库中专门为性能设计但不是最安全的内存分配的bug。
因此我们不得不在这两个并不完美的方法中选择一个。
鉴于方法一可能导致percona服务与上游的不兼容,我们更倾向于用方法二来解决问题,并期待着上游修复这个bug。
结论
如果发现mysqld进程占用内存很高,并不代表一定是内存泄漏。我们可以在Performance Schema中使用内存检测来了解进程是如何使用已分配的内存。也可以尝试替换内存库来更好地处理内存分配与释放。关于LD_RELOAD如何配置,请查阅MySQL用户手册对应页面 mysqld-safe和using-system。
链接1:https://www.percona.com/services/support/support-tiers-mysql
链接2:https://www.percona.com/services/support/support-tiers-mysql
链接3:https://jira.percona.com/browse/PS-5312
链接4:https://www.percona.com/blog/2019/05/02/mysql-memory-management-memory-allocators-and-operating-system/
链接5:https://jira.percona.com/browse/PS-5312
链接6:https://dev.mysql.com/doc/refman/8.0/en/mysqld-safe.html
链接7:https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/using-systemd.html
关注公众号“CloudQuery”了解更多信息!返回搜狐,查看更多
责任编辑: