centos下使用jemalloc解决Mysql内存泄漏问题
参考: MySQL bug:https://bugs.mysql.com/bug.php?id=83047&tdsourcetag=s_pcqq_aiomsg
https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md
(1)ptmalloc 是glibc的内存分配管理
(2)tcmalloc 是google的内存分配管理模块
(3)jemalloc 是BSD的提供的内存分配管理 (可以使用jemalloc优化Nginx)
三者jemalloc和tcmalloc的性能不分伯仲,而ptmalloc则要低一些
1、下载最新版jemalloc
git clone https://github.com/jemalloc/jemalloc
cd jemalloc
[root@bogon jemalloc]# cat VERSION
5.1.0-108-gc4063ce439523d382f2dfbbc5bf6da657e6badb0
2、安装步骤:
./autogen.sh
./configure
make
make install
[root@bogon jemalloc]# make install
/usr/bin/install -c -d /usr/bin
/usr/bin/install -c -m 755 bin/jemalloc-config /usr/bin
/usr/bin/install -c -m 755 bin/jemalloc.sh /usr/bin
/usr/bin/install -c -m 755 bin/jeprof /usr/bin
/usr/bin/install -c -d /usr/include/jemalloc
/usr/bin/install -c -m 644 include/jemalloc/jemalloc.h /usr/include/jemalloc
/usr/bin/install -c -d /usr/lib
/usr/bin/install -c -m 755 lib/libjemalloc.so.2 /usr/lib
ln -sf libjemalloc.so.2 /usr/lib/libjemalloc.so
/usr/bin/install -c -d /usr/lib
/usr/bin/install -c -m 755 lib/libjemalloc.a /usr/lib
/usr/bin/install -c -m 755 lib/libjemalloc_pic.a /usr/lib
/usr/bin/install -c -d /usr/lib/pkgconfig
/usr/bin/install -c -m 644 jemalloc.pc /usr/lib/pkgconfig
/usr/bin/install -c -d /usr/share/doc/jemalloc
/usr/bin/install -c -m 644 doc/jemalloc.html /usr/share/doc/jemalloc
/usr/bin/install: cannot stat ‘doc/jemalloc.html’: No such file or directory
make: *** [install_doc_html] Error 1
[root@bogon jemalloc]#
默认安装目录:
PREFIX : /usr/local
BINDIR : /usr/local/bin
DATADIR : /usr/local/share
INCLUDEDIR : /usr/local/include
LIBDIR : /usr/local/lib
MANDIR : /usr/local/share/man
3、配置mysqld使用jemalloc,需要将配置写到[mysqld_safe] section
[mysqld_safe]
malloc-lib=/usr/local/lib/libjemalloc.so
4. 如果直接使用sqld启动,
export LD_PRELOAD=/usr/local/lib/libjemalloc.so
然后启动sqld
5、查看jemalloc是否生效
lsof -n |grep jemalloc
[root@localhost mysql3306]# lsof -n |grep jemalloc
bash 11223 root cwd DIR 253,0 4096 35178 /software/jemalloc
mysqld 17475 mysql mem REG 253,0 4291512 18480172 /usr/lib/libjemalloc.so.2
mysqld 17475 17482 mysql mem REG 253,0 4291512 18480172 /usr/lib/libjemalloc.so.2
mysqld 17475 17483 mysql mem REG 253,0 4291512 18480172 /usr/lib/libjemalloc.so.2
mysqld 17475 17484 mysql mem REG 253,0 4291512 18480172 /usr/lib/libjemalloc.so.2
显示以上信息说明mysql已经成功加载jemalloc
或者
使用jemalloc(或tcmalloc)优化MYSQL(安装步骤)
malloc
-
wget tar xjf jemalloc-3.4.0.tar.bz2 cd jemalloc-3.4.0 ./configure --prefix=/usr/local/jemalloc --libdir=/usr/local/lib make && make install echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf ldconfig
[root@host-192-168-1-56 mysql]# cp /usr/local/lib/libjemalloc.so /usr/lib64/mysql/libjemalloc.so
mysql使用jemalloc
- 修改配置文件
- [mysqld_safe]
malloc-lib=/usr/lib64/mysql/libjemalloc.so ###指定libjemalloc.so 即可
重启mysql检查是否生效
- [root@host-192-168-1-56 mysql]# lsof -n | grep jemalloc
mysqld 6032 mysql mem REG 252,1 4781206 320288 /usr/lib64/mysql/libjemalloc.so
MySQL使用Jemalloc
鉴于jemalloc的诸多优点,计划使用jemalloc作为内存管理器来优化MySQL,下面是测试环境。
测试环境
CPU: ARM64
Memory: 512GB
OS: CentOS Linux release 8.3.2011
Kernel: 4.18.0-193.28.1.el8_2.aarch64
MySQL: 8.0.25
Test Tool: SysBench 1.0.20
Jemalloc: 5.2.1
jemalloc的安装和使用
# wget https://github.com/jemalloc/jemalloc/archive/refs/tags/5.2.1.tar.gz -O jemalloc-5.2.1.tar.gz
# tar xzvf jemalloc-5.2.1.tar.gz
# cd jemalloc-5.2.1
# ./autogen.sh
//安装到指定目录
# ./configure --prefix=/home/test-user/jemalloc-5.2.1-install
//编译并安装
# make; make install
//配置环境变量
# export LD_PRELOAD=/home/test-user/jemalloc-5.2.1-install/lib/libjemalloc.so
安装好MySQL后,通过如下命令检查jemalloc是否被正常使用(MySQL的安装请参考官方步骤,这里不再赘述)
# lsof -n |grep jemalloc
下图显示MySQL已经正常使用jemalloc

测试用例
异常问题
压测过程中发现内存使用“异常”:MySQL进程占用的物理内存超过了100GB。

不使用jemalloc切换回默认的glibc后,内存占用降低到了7GB,和以往的测试结果一致。

从测试结果看,使用jemalloc作为内存管理器时内存使用量激增,需要进一步分析原因。内存使用量是否合理?是否和架构相关?
问题分析
第一阶段分析
1. 复现“问题”
首先需要确定该“问题”是否在x86架构上也存在,是否和操作系统或内核版本相关。
为了快速验证以上疑问,在AWS上分别创建x86实例(m5)和arm64实例(m6g)进行测试, 并没有复现“问题”。这两个实例默认的操作系统是Amazon Linux 2,而本地测试时使用的是CentOS8,在m6g上安装CentOS8重新测试,“问题”复现。测试结果如下:

2. 对比分析
对比测试环境,分析它们不同点,我们发现该“问题”只有在内核page size是64KB时才会出现。
另外,根据前文介绍,jemalloc中extent会基于page size分配内存。而且,深入分析jemalloc代码后还发现有多个数据结构的内存分配都涉及到page size,比如size_class, bin, extents, arena等等。
页表在操作系统中作为最基础的内存分配结构,ARM64支持4K、16K、64K不同大小的页表,x86只支持4KB。而本地测试使用的ARM64 CentOS的默认page size就是64KB,所以初步判断该“问题”和page size的配置相关。
3. 解决方法
即然ARM64架构支持多种page size,而page size为4KB时没有出现问题,那么可以修改ARM64 CentOS8的内核默认的page size来解决该"问题"。
修改page size方法
由于内核当前页表大小只支持静态配置,不支持动态修改,所以需要重新编译内核。
修改方法如下:
- 在 https://www.kernel.org/ 获取需要的内核版本
-
解压并修改内核配置参数
# tar xf linux-x.x.x.tar.xz # cd linux-x.x.x # cp /boot/config-xxx .config # make menuconfig在图形菜单中找到“Kernel Features-> Page size”,选择4KB并保存配置

-
编译并安装新的内核
# make -j # make modules_install # make install -
重启进入新的内核,参看page size是否修改成功
# getconf PAGE_SIZE 4096
4. 验证
修改page size为4KB后重新测试,jemalloc内存使用量和glibc接近。测试结果如下:

5. 潜在问题
至此该“问题”似乎可以通过修改page size来解决。但是,如果用户仍然需要使用64KB的页表,该方法将不再适用。
实际上,jemalloc本身支持编译参数“--with-lg-page=16”,该参数可以使jemalloc在page size为4KB时复用多个页面来达到使用64KB页面的效果。
尝试在4KB page size的系统下加入该编译参数,并没有出现内存使用量激增的现象。
这说明除了page size,还有其他因素影响了jemalloc的内存分配,仍然需要进一步分析。
第二阶段分析
1. micro-benchmark
通过以上测试发现该“问题”和MySQL并没有直接关系。为了简化分析和复现过程,单独开发了一个micro-benchmark https://github.com/machuang1983/jemalloc_micro_benchmark
该程序用于建立多个线程,每个线程分配一定内存,程序运行过程中实时打印进程的内存使用情况。
通过micro-benchmark可以快速复现问题。测试结果显示,每新建一个线程就会消耗1GB左右的内存。测试结果如下:

再次简化测试,直接运行单线程程序,如sleep 100,进程就会占用1GB内存。

由此看见,jemalloc针对一个线程进行内存初始化分配时就会分配1GB内存。需要深入分析jemalloc具体的分配机制。
2. 深入分析jemalloc代码
按前文所述,jemalloc的内存分配涉及到多个数据结构,我们结合gdb单步执行来分析jemalloc代码,同时实时查看内存占用的变化,由此定位到关键代码。
调试过程中发现,base会基于默认的hugepage size分配内存,分配之后监控到内存使用量突然增大,具体代码在 https://github.com/jemalloc/jemalloc/blob/dev/src/base.c#L46-L49

继续搜索hugepage size相关代码,还发现另一处使用它来分配内存,代码在https://github.com/jemalloc/jemalloc/blob/master/src/arena.c#L2052

由此可见除了page size,hugepage size对jemalloc的内存分配也有影响。通常hugepage size比page size大得多,所以hugepage size的影响会更大。
3. hugepage
内存管理采用"分页机制",但是当运行内存需求量较大时,默认page大小的页面会导致较多的TLB miss和缺页中断,从而大大影响应用程序性能。所以,有些场景希望可以使用更大的内存页作为映射单位,因此引入了hugepage。
不同架构支持的hugepage size不同,见下表:

4. 解决方法
ARM64 CentOS在page size=64KB时,默认hugepage size是512MB,jemalloc的base会以512MB来分配内存,而当page size=4KB时,默认hugepage size是2MB。所以回顾前面的测试,修改page size后问题消失的主要原因是默认的hugepage size改变导致的。
默认hugepage size修改方法
-
修改启动参数“default_hugepagesz=2M”
ARM64支持多种hugepage size,可以使用hugepagesz启动参数进行调整,无需重新编译内核。-
永久修改
- Centos: Set default_hugepagesz=2M in /boot/grub2/grubenv file
- Ubuntu: Set default_hugepagesz=2M to GRUB_CMDLINE_LINUX in /etc/default/grub file, then run “update-grub”
-
临时修改
- 内核启动时,输入"e"进入修改启动选项界面,加入参数“default_hugepagesz=2M”,然后输入"ctrl+x"启动内核。
-
- jemalloc编译参数"--with-lg-hugepage=21"
jemalloc支持编译参数"--with-lg-hugepage=21",替代系统的默认的hugepage size为2MB。建议使用该方法。
5. 验证
修改默认hugepage size后测试结果(sysbench使用256线程压测)如下:

测试结果显示,将hugepage size改为2MB以后,jemalloc的内存使用情况和glibc接近。
总结
该"问题"和架构无关,jemalloc作为内存管理器,如果默认hugepage size较大,会导致软件占用较大的内存,jemalloc提供了编译参数"--with-lg-hugepage=21"来降低这个影响。
由于ARM64支持更多类型的page size和hugepage size,用以提升软件的性能。所以用户在ARM64系统上使用jemalloc时,需要关注默认的page size和hugepage size,并根据具体需求做出相应的调整。
相关文章:
centos下使用jemalloc解决Mysql内存泄漏问题
参考: MySQL bug:https://bugs.mysql.com/bug.php?id83047&tdsourcetags_pcqq_aiomsg https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md (1)ptmalloc 是glibc的内存分配管理 (2)tcmalloc…...
【100天精通python】Day41:python网络爬虫开发_爬虫基础入门
目录 专栏导读 1网络爬虫概述 1.1 工作原理 1.2 应用场景 1.3 爬虫策略 1.4 爬虫的挑战 2 网络爬虫开发 2.1 通用的网络爬虫基本流程 2.2 网络爬虫的常用技术 2.3 网络爬虫常用的第三方库 3 简单爬虫示例 专栏导读 专栏订阅地址:https://blog.csdn.net/…...
开源和自研——机器人
双足机器人: MPC技术:封闭性非常高。没有开源方案可抄。 因为开源,不需要从0构建。 这也是前两年,国外一开源华为就遥遥领先。 射频芯片/射频天线:技术封闭。华为虽然做通信,但却没有攻破。 鸿蒙&#…...
【AIGC 讯飞星火 | 百度AI|ChatGPT| 】智能对比
AI智能对比 🍸 前言🍺 概念类对比🍵 讯飞🍵 百度AI🍵 chatGPT 🍹 功能类对比☕ 讯飞☕ 百度AI☕ chatGPT 🥃 可输入字数对比🥤 百度AI🥤 讯飞🥤 chatGPT &…...
Wazuh安装及使用
环境配置 官方网址Quickstart Wazuh documentation 可以选择Elastic Stack安装,也可以选择下载虚拟机(OVA)安装 这里展示虚拟机安装 下载好文档中提供的文件 虚拟机配置要求 在VM左上角 文件->打开->刚刚下载的.ova文件,…...
docker pull 设置代理 centos
On CentOS the configuration file for Docker is at: /etc/sysconfig/docker 用 root 权限打开 text editor sudo gedit 注意 加引号 Adding the below line helped me to get the Docker daemon working behind a proxy server: HTTP_PROXY“http://<proxy_host>:&…...
仪表板展示 | DataEase看中国:2023年中国电影市场分析
背景介绍 随着《消失的她》、《变形金刚:超能勇士崛起》、《蜘蛛侠:纵横宇宙》、《我爱你》等国内外影片的上映,2023年上半年的电影市场也接近尾声。据国家电影专资办初步统计,上半年全国城市院线票房达262亿元,已经超…...
在APP中如何嵌入小游戏?
APP内嵌游戏之所以能火爆,主要是因为互联网对流量的追求是无止境的,之前高速增长的红利期后,获取新的流量成为各大厂商的挑战,小游戏的引入,就是这个目的,为已有的产品赋能,抢占用户注意力和使用…...
神经网络基础-神经网络补充概念-02-逻辑回归
概念 逻辑回归是一种用于二分分类问题的统计学习方法,尽管名字中带有"回归"一词,但实际上它用于分类任务。逻辑回归的目标是根据输入特征来预测数据点属于某个类别的概率,然后将概率映射到一个离散的类别标签。 逻辑回归模型的核…...
DICOM图像的常用一些参数解析
医学图像DICOM医学影像文件格式详解 Dicom文件基本操作 DICOM图像参数? 像素:构成图片的小色点。图像每个维度的像素个数——该维度一共有多少个均匀分布的像素点。 分辨率(单位DPI):每英寸(Inch…...
Java虚拟机(JVM):虚拟机栈溢出
一、概念 Java虚拟机栈溢出(Java Virtual Machine Stack Overflow)是指在Java程序中,当线程调用的方法层级过深,导致栈空间溢出的情况。 Java虚拟机栈是每个线程私有的,用于存储方法的调用和局部变量的内存空间。每当…...
MySQL流程控制
流程控制 顺序结构: 程序从上往下依次执行分支结构: 程序按条件进行选择执行,从两条或多条路径中选择一条执行。循环结构: 程序满足一定条件下,重复执行一组语句 针对于MySQL的流程控制语句主要有3类。注意ÿ…...
智安网络|深入比较:Sass系统与源码系统的差异及选择指南
随着前端开发的快速发展,开发人员需要使用更高效和灵活的工具来处理样式表。在这个领域,Sass系统和源码系统是两个备受关注的选项。 Sass系统 Sass(Syntactically Awesome Style Sheets)是一种CSS预处理器,它扩展了CS…...
Day14 01-Shell脚本编程详解
文章目录 第一章 Shell编程【重点】1.1. Shell的概念介绍1.1.1. 命令解释器4.1.1.2. Shell脚本 1.2. Shell编程规范1.2.1. 脚本文件的结构1.2.2. 脚本文件的执行 1.3. Shell的变量1.3.1. 变量的用法1.3.2. 变量的分类1.3.3. 局部变量1.3.4. 环境变量1.3.5. 位置参数变量1.3.6. …...
NVIDIA GPU驱动和CUDA工具包 Linux CentOS 7 在线安装指南
挑选指定系统和对应的GPU型号下载驱动和CUDA工具包: Linux CentOS安装NVIDIA GPU驱动程序和NVIDIA CUDA工具包_centos安装显卡驱动和cuda_Entropy-Go的博客-CSDN博客 相比之下,本文是在线安装NVIDIA GPU驱动和CUDA工具包方式,省去挑选对应正确安装包的烦…...
Php“牵手”拼多多商品详情页数据采集方法,拼多多API接口申请指南
拼多多详情接口 API 是开放平台提供的一种 API 接口,它可以帮助开发者获取商品的详细信息,包括商品的标题、描述、图片等信息。在电商平台的开发中,详情接口API是非常常用的 API,因此本文将详细介绍详情接口 API 的使用。 一、拼…...
未来公文的智能化进程
随着技术的飞速发展,公文——这个有着悠久历史的官方沟通方式,也正逐步走向智能化的未来。自动化、人工智能、区块链...这些现代科技正重塑我们的公文制度,让其变得更加高效、安全和智慧。 1.语义理解与自动生成 通过深度学习和NLPÿ…...
C语言:深度学习知识储备
目录 数据类型 每种类型的大小是多少呢? 变量 变量的命名: 变量的分类: 变量的作用域和生命周期 作用域: 生命周期: 常量 字符串转义字符注释 字符串: 转义字符 操作符: 算术操作符…...
探索大模型时代下的算法工程师前景与发展路径
文章目录 大模型时代的挑战与机遇从算法到工程:技能升级的必要性发展路径与职业规划路径一:深耕研究领域路径二:工程实践与部署路径三:跨界合作与解决复杂问题路径四:教育培训和技术普及 不断学习与更新知识结论 &…...
【福建事业单位-综合基础知识】03行政法
【福建事业单位-综合基础知识】03行政法 1.行政法概述(原则重点)行政主体范围 行政行为总结 二.行政处罚2.1行政处罚的种类总结 行政法框架 1.行政法概述(原则重点) 行政法的首要原则是合法;自由裁量——合理行政&…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
