• ADADADADAD

    MySQL内存的bug分析[ mysql数据库 ]

    mysql数据库 时间:2024-11-25 18:01:09 热度:1℃

    作者:文/会员上传 下载docx

    简介:

    所有percona所支持的客户都有获得bug修复的资格,但他们也有不同的选择。比如,vip客户在软件补丁正式发布之前就可以获得hotfiix版本,高级客户甚至不需要使用percona的软件,我们

    以下为本文的正文内容,请查阅,本站为公益性网站,复制本文以及下载DOC文档全部免费。

    所有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分析.docx

    将本文的Word文档下载到电脑

    推荐度:

    下载
    热门标签: mysql
    ADADAD