searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

记一次数据库 oom 问题排查

2024-09-05 09:26:36
5
0

>>环境信息:

操作系统版本: CTyunOS release 2 22.06.1

内核版本: 4.19.90-2102.2.0.0064.ctl2.x86_64

数据库初始版本: 5.7.39, for Linux (x86_64)

>>问题梳理

1,2022.11 创建安装实例

3台物理机64C768G,8set1主2从

部署完成后,业务未上线,监控无异常

1,2024.02 参照《MySQL加载Jemalloc库的排查手段及说明(含arm版)》修复jemalloc

修复后,频繁出现Out of memory导致的实例重启(空闲内存充足)

2,关闭numa,协调主机排查其他软硬件

问题依旧

3,2022.06.25 关闭jemalloc

堆栈信息大量内存和libjemalloc相关信息,测试关闭jemalloc

OOM重启不再出现,mysqld进程内存泄漏且free较大情况下swap耗尽

4,2024208.09 尝试升级至5.7.46(默认开启jemalloc)

仍然频繁出现Out of memory导致的实例重启

5,2022.08.10 调整jemalloc配置为系统库文件

无效,仍然频繁出现Out of memory导致的实例重启

6,2022.08.11 尝试升级最新版本至5.7.49

暂无异常,继续观察

系统频繁重启,目前已经替换最新的包,担心再次oom及排查之前oom的原因,今天上午10点找DBA分析排查,暂未找到原因。

2. 原因分析

从错误日志中看出,出错都是在内存分配时,在jemalloc下的 throw_bad_castv 抛出 bad_alloc 异常

提示关注下虚拟内存后,同事找出频繁 core 的实例与稳定实例间,系统配置 vm.max_map_count 有所不同。

7. 观察发现,开启jemalloc后虽然物理内存无泄漏,但是虚拟内存仍然存在泄漏现象

通过pmap -x <msyql pid>查看进程使用内存的详细信息

$ pmap -x 739642|grep anon|wc -l --开启jemalloc

24773

$ pmap -x 2876664|grep anon|wc -l --未使用jemalloc

2602

开启J版内存回收的mysqld有大量的anon(匿名内存块),虽然物理内存释放,但是内存映射区仍然保留,且不断增加

怀疑是内存映射区耗尽导致

8. 调整vm.max_map_count 验证

vm.max_map_count默认为65530 ,上次升级5.7.49后曾优化过内核设置vm.max_map_count=262144,所以升级后至今未触发重启

为验证,调小vm.max_map_count,超过内存映射区的mysqld立即重启

以上,mysqld 频繁OOM原因为mysqld进程映射有大量的anon(匿名内存块)导致进程内存映射区耗尽导致

对于开启jemalloc后,mysqld进程映射大量的anon(匿名内存块),虚拟内存泄漏问题仍需进一步分析

找到一个文章分析,与问题完全吻合:


大概意思是,连续的mmap是会合并为一个记录,count还是1,但连续的区域中间部分munmap了,就会分开成两个区域,count增多。意思是碎片化过多了,导致系统限制新映射区创建。

结合用户提供的 maps 文件,可看到用户映射区记录的映射是连续的地址空间,并且使用(rw-p)和释放的(---p) 梅花间竹地存在,符合连续分配后,释放不再使用内存,导致碎片过多情况。

3. 解决方案

调大 max_map_count 可以简单粗暴的解决这个问题。最终结果,将默认数值65530 调大到 262144

0条评论
作者已关闭评论
lcken
3文章数
0粉丝数
lcken
3 文章 | 0 粉丝
lcken
3文章数
0粉丝数
lcken
3 文章 | 0 粉丝
原创

记一次数据库 oom 问题排查

2024-09-05 09:26:36
5
0

>>环境信息:

操作系统版本: CTyunOS release 2 22.06.1

内核版本: 4.19.90-2102.2.0.0064.ctl2.x86_64

数据库初始版本: 5.7.39, for Linux (x86_64)

>>问题梳理

1,2022.11 创建安装实例

3台物理机64C768G,8set1主2从

部署完成后,业务未上线,监控无异常

1,2024.02 参照《MySQL加载Jemalloc库的排查手段及说明(含arm版)》修复jemalloc

修复后,频繁出现Out of memory导致的实例重启(空闲内存充足)

2,关闭numa,协调主机排查其他软硬件

问题依旧

3,2022.06.25 关闭jemalloc

堆栈信息大量内存和libjemalloc相关信息,测试关闭jemalloc

OOM重启不再出现,mysqld进程内存泄漏且free较大情况下swap耗尽

4,2024208.09 尝试升级至5.7.46(默认开启jemalloc)

仍然频繁出现Out of memory导致的实例重启

5,2022.08.10 调整jemalloc配置为系统库文件

无效,仍然频繁出现Out of memory导致的实例重启

6,2022.08.11 尝试升级最新版本至5.7.49

暂无异常,继续观察

系统频繁重启,目前已经替换最新的包,担心再次oom及排查之前oom的原因,今天上午10点找DBA分析排查,暂未找到原因。

2. 原因分析

从错误日志中看出,出错都是在内存分配时,在jemalloc下的 throw_bad_castv 抛出 bad_alloc 异常

提示关注下虚拟内存后,同事找出频繁 core 的实例与稳定实例间,系统配置 vm.max_map_count 有所不同。

7. 观察发现,开启jemalloc后虽然物理内存无泄漏,但是虚拟内存仍然存在泄漏现象

通过pmap -x <msyql pid>查看进程使用内存的详细信息

$ pmap -x 739642|grep anon|wc -l --开启jemalloc

24773

$ pmap -x 2876664|grep anon|wc -l --未使用jemalloc

2602

开启J版内存回收的mysqld有大量的anon(匿名内存块),虽然物理内存释放,但是内存映射区仍然保留,且不断增加

怀疑是内存映射区耗尽导致

8. 调整vm.max_map_count 验证

vm.max_map_count默认为65530 ,上次升级5.7.49后曾优化过内核设置vm.max_map_count=262144,所以升级后至今未触发重启

为验证,调小vm.max_map_count,超过内存映射区的mysqld立即重启

以上,mysqld 频繁OOM原因为mysqld进程映射有大量的anon(匿名内存块)导致进程内存映射区耗尽导致

对于开启jemalloc后,mysqld进程映射大量的anon(匿名内存块),虚拟内存泄漏问题仍需进一步分析

找到一个文章分析,与问题完全吻合:


大概意思是,连续的mmap是会合并为一个记录,count还是1,但连续的区域中间部分munmap了,就会分开成两个区域,count增多。意思是碎片化过多了,导致系统限制新映射区创建。

结合用户提供的 maps 文件,可看到用户映射区记录的映射是连续的地址空间,并且使用(rw-p)和释放的(---p) 梅花间竹地存在,符合连续分配后,释放不再使用内存,导致碎片过多情况。

3. 解决方案

调大 max_map_count 可以简单粗暴的解决这个问题。最终结果,将默认数值65530 调大到 262144

文章来自个人专栏
问题分析
3 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0