mysql 自动管理内存_MySQL内存管理,内存分配器和操作系统

news/2024/7/7 20:30:17

导读

作者: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...

实现WL #5538 InnoDB全文搜索支持与合并 - https://github.com/mysql/mysq... - 也存在同样的问题问题

修复方法

我们有两种方法来修复这个问题:

1.修改InnoDB全文索引的实现

2.使用自定义内存库,例如jemalloc

这两种方法都有各自的优缺点。

方法1 :意味着我们引入了与软件上游不兼容性的风险,这可能会导致新版本中出现未知的错误。也意味着彻底重写InnoDB全文索引部分代码,这在用户们使用的GA版本中是有风险的。

方法2 则意味着我们可能会命中一些jemalloc库中专门为性能设计但不是最安全的内存分配的bug。

因此我们不得不在这两个并不完美的方法中选择一个。

鉴于方法一可能导致percona服务与上游的不兼容,我们更倾向于用方法二来解决问题,并期待着上游修复这个bug。

结论

如果发现mysqld进程占用内存很高,并不代表一定是内存泄漏。我们可以在Performance Schema中使用内存检测来了解进程是如何使用已分配的内存。也可以尝试替换内存库来更好地处理内存分配与释放。关于LD_RELOAD如何配置,请查阅MySQL用户手册对应页面 mysqld-safe和using-system。

a230f1844640e4cf725b865e4c1a9ce5.png


http://lihuaxi.xjx100.cn/news/241442.html

相关文章

进程与进程调度优先

这里引用百度百科,先说一下进程:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中&#xff0c…

简单几步写一个laravel扩展包

为什么80%的码农都做不了架构师?>>> laravel使用composer来管理扩展包,理解composer和laravel的开发模式,可以通过简单的几个步骤,快速写出一个laravel扩展包。 全新的laravel5.4环境安装 composer create-project la…

DDoS攻击已成掩盖真实网络攻击的烟雾弹

近年来,随着分布式拒绝服务(DDoS)攻击在规模、频率以及复杂性等方面的持续上升,让全球众多企业遭受到不同程度的损失。然而,通过分析安全专家们还发现,有些DDoS攻击仅仅只是网络犯罪分子为了掩盖其真实攻击…

mysql 绑定参数_MySQL 使用 Perl 绑定参数和列

SQL 语句通常是动态构建的,用户提供一些输入,并将其内置到语句中。 程序员每次处理用户的输入时都必须谨慎。 它具有一些严重的安全隐患。 动态构建 SQL 语句的推荐方法是使用参数绑定。绑定参数可以防止 SQL 注入程序。 它会自动转义一些特殊字符并允许…

(C++)1010 一元多项式求导 --需二刷

笔记&#xff1a;学习利用数组下标表示序列之外信息的方法 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std;int main(){int num[1010] {0}; //num[a] b 其中a是系数&#xff0c;b是指数 int coe,id…

(C++)1002 A+B for Polynomials

笔记&#xff1a;1.两个不为0的数相加可能为0 2.浮点数的比较方法 3.输出的时候格式怎么办 本题空格放在哪有门道 4.不需要三个数组&#xff0c;一个就可以了&#xff0c;第二个“数组”输入的时候直接加在第一个上面 #include<cstdio> #include<cmath> #inclu…

命令行接口(CLI)将被取而代之,它不再是网络运维的主要工具

Gartner声称&#xff1a;到2020年&#xff0c;CLI的使用将日渐式微。 多年来&#xff0c;网络工程师依赖命令行接口&#xff1b;据市场研究公司Gartner的分析师们声称&#xff0c;但是这种使用很普遍的工具正在迅速让位于配置和运维网络的其他方法。实际上&#xff0c;他们预测…

nm 命令

最好是阅读 man nmnm - list symbols from object filesIf lowercase, the symbol is local; if uppercase, the symbol is global (external)其输出结果&#xff1a;"A" The symbol’s value is absolute, and will not be changed by further linking."B"…