共计 1438 个字符,预计需要花费 4 分钟才能阅读完成。
本篇内容介绍了“MySQL 内存的 bug 分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
所有 percona 所支持的客户都有获得 bug 修复的资格,但他们也有不同的选择。比如,vip 客户在软件补丁正式发布之前就可以获得 hotfiix 版本,高级客户甚至不需要使用 percona 的软件,我们也可以为他们把补丁推到上游。但对于与 percona 产品来说,所有支持等级都有权得到 bug 修复。
即便如此,这并不意味着我们会修复所有的意外情况,即使我们接受这种情况为一个有效 bug。做出这样的决定的原因之一可能是这个意外情况虽然很明确是错误的,但对于 percona 产品本身来说确实一个产品需求
作为学习案例的一个 bug
最近一个很好的案例是 PS-5312 链接 3 ——这个 bug 可在上游复现并被记录在 bugs.mysql.com/95065 链接 4。
这个报告阐述了一种情况,当访问 InnoDB 的全文索引的时候会导致内存使用量增长。这种情况出现在一些全文索引的查询,内存会持续增长直到达到最大值,并且很长时间不会释放。
来自 Percona 工程团队的 Yura Sorokin 研究表明,这种情况并不属于内存泄漏范畴。
当 InnoDB 解析一个全文查询时,它会在 fts_query_phrase_search 函数中创建一个内存堆,这个堆可能增长到 80M。另外,这个过程还会使用到大量非连续块 (mem_block_t) 进而产生的内存碎片。
在函数出口,这些内存堆会被释放。InnoDB 会为其分配的每一个块做这个操作。在函数执行结束时,调用一个内存分配器库中的 free()操作,比如 malloc 或者 jemalloc。从 MySQL 本身来看,这都是没问题的,不存在内存泄漏。
然而,free()函数被调用时确实应该释放内存,但不需要将其返回给操作系统。如果内存分配器发现这些内存块马上还需要被用到,则会将他们保留住继续用于 mysqld 进程。这就解释了为什么 mysqld 在完成工作及释放内存都结束后还会占用大量内存。
这个在实际生产中并不是一个大问题,按道理不应该造成任何事故。但是如果你需要更快地将内存返回给操作系统,你可以尝试非传统的内存分配器,类似 jemallolc。它被证明可以解决 PS-5312 链接 5 的问题。
另一个改善内存管理的因素是 cpu 内核数量:在测试中,cpu 核数越多,内存返回给操作系统的速度会越快。这可能是你拥有多个 CPU,而其中一个可专门用作内存分配器释放内存给操作系统。
修复方法
我们有两种方法来修复这个问题:
1. 修改 InnoDB 全文索引的实现
2. 使用自定义内存库,例如 jemalloc
这两种方法都有各自的优缺点。
方法 1 意味着我们引入了与软件上游不兼容性的风险,这可能会导致新版本中出现未知的错误。也意味着彻底重写 InnoDB 全文索引部分代码,这在用户们使用的 GA 版本中是有风险的。
方法 2 则意味着我们可能会命中一些 jemalloc 库中专门为性能设计但不是最安全的内存分配的 bug。
因此我们不得不在这两个并不完美的方法中选择一个。
鉴于方法一可能导致 percona 服务与上游的不兼容,我们更倾向于用方法二来解决问题,并期待着上游修复这个 bug。
“MySQL 内存的 bug 分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!