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

  1. 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

  1. 修改配置文件
  2. [mysqld_safe]
    malloc-lib=/usr/lib64/mysql/libjemalloc.so             ###指定libjemalloc.so 即可

重启mysql检查是否生效

  1. [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

title=

测试用例

sysbench启动80个线程对MySQL进行读写压测。

异常问题

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

title=


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

title=


从测试结果看,使用jemalloc作为内存管理器时内存使用量激增,需要进一步分析原因。内存使用量是否合理?是否和架构相关?

回到顶部

问题分析

第一阶段分析

1. 复现“问题”

首先需要确定该“问题”是否在x86架构上也存在,是否和操作系统或内核版本相关。

为了快速验证以上疑问,在AWS上分别创建x86实例(m5)和arm64实例(m6g)进行测试, 并没有复现“问题”。这两个实例默认的操作系统是Amazon Linux 2,而本地测试时使用的是CentOS8,在m6g上安装CentOS8重新测试,“问题”复现。测试结果如下:

title=

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并保存配置

    title=

  • 编译并安装新的内核

    # make -j
    # make modules_install
    # make install
  • 重启进入新的内核,参看page size是否修改成功

    # getconf PAGE_SIZE
    4096
4. 验证

修改page size为4KB后重新测试,jemalloc内存使用量和glibc接近。测试结果如下:

title=

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左右的内存。测试结果如下:

image.png

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

title=


由此看见,jemalloc针对一个线程进行内存初始化分配时就会分配1GB内存。需要深入分析jemalloc具体的分配机制。

2. 深入分析jemalloc代码

按前文所述,jemalloc的内存分配涉及到多个数据结构,我们结合gdb单步执行来分析jemalloc代码,同时实时查看内存占用的变化,由此定位到关键代码。

调试过程中发现,base会基于默认的hugepage size分配内存,分配之后监控到内存使用量突然增大,具体代码在 https://github.com/jemalloc/jemalloc/blob/dev/src/base.c#L46-L49
 

title=


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

title=

由此可见除了page size,hugepage size对jemalloc的内存分配也有影响。通常hugepage size比page size大得多,所以hugepage size的影响会更大。

3. hugepage

内存管理采用"分页机制",但是当运行内存需求量较大时,默认page大小的页面会导致较多的TLB miss和缺页中断,从而大大影响应用程序性能。所以,有些场景希望可以使用更大的内存页作为映射单位,因此引入了hugepage。

不同架构支持的hugepage size不同,见下表:

title=

4. 解决方法

ARM64 CentOS在page size=64KB时,默认hugepage size是512MB,jemalloc的base会以512MB来分配内存,而当page size=4KB时,默认hugepage size是2MB。所以回顾前面的测试,修改page size后问题消失的主要原因是默认的hugepage size改变导致的。

默认hugepage size修改方法
  1. 修改启动参数“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"启动内核。
  2. jemalloc编译参数"--with-lg-hugepage=21"
    jemalloc支持编译参数"--with-lg-hugepage=21",替代系统的默认的hugepage size为2MB。建议使用该方法。
5. 验证

修改默认hugepage size后测试结果(sysbench使用256线程压测)如下:
 

title=


测试结果显示,将hugepage size改为2MB以后,jemalloc的内存使用情况和glibc接近。

回到顶部

总结

该"问题"和架构无关,jemalloc作为内存管理器,如果默认hugepage size较大,会导致软件占用较大的内存,jemalloc提供了编译参数"--with-lg-hugepage=21"来降低这个影响。

由于ARM64支持更多类型的page size和hugepage size,用以提升软件的性能。所以用户在ARM64系统上使用jemalloc时,需要关注默认的page size和hugepage size,并根据具体需求做出相应的调整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/96357.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何做好科技文献资料的翻译!

我们知道,科技文献是工程技术人员的重要参考文献,翻译科技文献资料有助于促进国内外科技知识和技术的传播。那么,如何做好科技文献资料的翻译,专业科技文献翻译哪家好? 据了解,科技文献翻译是一种以应用为主…

迈向通用听觉人工智能!清华电子系、火山语音携手推出认知导向的听觉大语言模型SALMONN

日前,清华大学电子工程系与火山语音团队携手合作,推出认知导向的开源听觉大语言模型SALMONN (Speech Audio Language Music Open Neural Network)。 大语言模型 SALMONN LOGO 相较于仅仅支持语音输入或非语音音频输入的其他大模型,SALMONN对…

insightface安装过程中提示 Microsoft Visual C++ 14.0 or greater is required.

pip install insightface安装过程中提示 Microsoft Visual C 14.0 or greater is required.Get it with "Microsoft C Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/ 根据提示网站访问官网下载生成工具 打开软件后会自动更新环境&#…

AI搜索引擎助力科学家创新

开发者希望通过帮助科学家从大量文献中发现联系从而解放科学家,让他们专注于发现和创新。 图片来源:The Project Twins 对于专注于历史的研究者Mushtaq Bilal来说,他在未来科技中投入了大量时间。 Bilal在丹麦南部大学( Universit…

「UG/NX」Block UI 曲线收集器CurveCollector

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#

机器人的运动范围

声明 该系列文章仅仅展示个人的解题思路和分析过程,并非一定是优质题解,重要的是通过分析和解决问题能让我们逐渐熟练和成长,从新手到大佬离不开一个磨练的过程,加油! 原题链接 机器人的运动范围https://leetcode.c…

github以及上传代码处理

最近在github上传代码的时候出现了: /video_parser# git push -u origin main Username for https://github.com: gtnyxxx Password for https://gtny2010github.com: remote: Support for password authentication was removed on August 13, 2021. remote: Plea…

VB6编程IEEE浮点算法实践

纯代码实现浮点计算实际上对浮点算法的再实践。IEEE浮点表示法是Modbus RTU协议至今还在用的传送编码,更是WITS 1记录标准的基础。以往实现 MKI、CVI,MKL、CVL,MKS、CVS,MKD、CVD在高级语言里封装了现成的语句,现在Pow…

创建和运行 Ansible 临时命令

创建和运行 Ansible 临时命令 作为系统管理员,您需要在受管节点上安装软件。 请按照正文所述,创建一个名为 /home/curtis/ansible/adhoc.sh 的 shell 脚本,该脚本将使用 Ansible 临时命令在各个受管节点上安装 yum 存储库: 存储库…

【C++】函数指针

2023年8月18日,周五上午 今天在B站看Qt教学视频的时候遇到了 目录 语法和typedef或using结合我的总结 语法 返回类型 (*指针变量名)(参数列表)以下是一些示例来说明如何声明不同类型的函数指针: 声明一个不接受任何参数且返回void的函数指针&#xf…

OJ练习第151题——克隆图

克隆图 力扣链接:133. 克隆图 题目描述 给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。 示例 分析 对于一张图而言,它的深拷贝即构建一张与原图结构,值均一样的图,但是…

POSTGRESQL 关于安装中自动启动的问题 详解

开头还是介绍一下群,如果感兴趣Polardb ,mongodb ,MySQL ,Postgresql ,redis ,SQL SERVER ,ORACLE,Oceanbase 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请加 liuaustin3微信号 &…

Python “贪吃蛇”游戏,在不断改进中学习pygame编程

目录 前言 改进过程一 增加提示信息 原版帮助摘要 pygame.draw pygame.font class Rect class Surface 改进过程二 增加显示得分 改进过程三 增加背景景乐 增加提示音效 音乐切换 静音切换 mixer.music.play 注意事项 原版帮助摘要 pygame.mixer pygame.mix…

代码随想录算法训练营第三十八天 | 理论基础,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯

代码随想录算法训练营第三十八天 | 理论基础,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯 理论基础什么是动态规划动态规划的解题步骤动态规划应该如何debug 509. 斐波那契数递归解法 70. 爬楼梯746. 使用最小花费爬楼梯 理论基础 视…

微信小程序:函数节流与函数防抖

目录 问题引入: 定义 解决方案:函数节流 一、案例举例 1.页面展示 2.search.wxml标签展示 3.search.js展示 4.结果展示 二、函数节流解决问题 1.函数 2.实例应用 三、函数防抖解决问题 1.函数 2.原理 3.应用场景 4.应用实例 总结 问题引入…

Python3的print用法

目录 一:print语法 二:print结尾参数end用法 三:print分隔符参数sep用法 四:print固定宽度字符输出 一:print语法 print(*objects, sep , end\n, filesys.stdout, flushFalse) 参数解释: &q…

【计算机设计大赛】国赛一等奖项目分享——基于多端融合的化工安全生产监管可视化系统

文章目录 一、计算机设计大赛国赛一等奖二、项目背景三、项目简介四、系统架构五、系统功能结构六、项目特色(1)多端融合(2)数据可视化(3)计算机视觉(目标检测) 七、系统界面设计&am…

虹科展会 | 自动驾驶展品:上海汽车测试展精彩回顾

2023年8月9日-8月11日,上海国际汽车测试及质量监控博览会在上海圆满落幕。本次展会提供了一个了解最新汽车测试及质量监控技术、产品和趋势的机会,同时也是汽车测试及质量监控领域的专业人士和业内人士的重要交流平台。 雅名特是虹科旗下子公司&#xff…

springcloud3 hystrix实现服务熔断的案例配置3

一 hystrix的熔断原理 1.1 hystrix的熔断原理 在springcloud的框架里,熔断机制是通过hystrix实现,hystrix会监控服务之间的调用。当失败调用达到一定的阈值,默认是5s内失败20次,就会启用hystrix的熔断机制,使用命Hy…

Python Opencv实践 - 图像透射变换

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) rows,cols img.shape[:2] print(rows,cols)#opencv中的透射变换,需要一个3x3透射变换矩阵 #这个矩阵可以通过…