glibc缺陷居然会导致MySQL卡住?

GHOST漏洞深度解析:glibc堆内存管理缺陷与全平台防护实战 GHOST(CVE-2015-0235)是影响Linux生态底层glibc组件的高危堆内存管理漏洞,其本质并非传统缓冲区溢出,而是__nss_hostname_digits_dots函数在堆块重用过程中污染malloc_chunk元数据,导致远程代码执行。该漏洞利用DNS解析这一基础网络行为,绕过ASLR与常规权限控制,广泛影响glibc 2.2–2.17版本系统,包括Ubuntu、CentOS及主流国产Linux发行版。技术价值在于揭示了C标准库与内存分配器协同设计中的隐蔽风险;典型应用场景涵盖OpenS 阅读详情

问题来源:

版本:5.7.25。

现象:备机主从延迟不断变大,无法登陆数据库,建立连接时卡住,但很快恢复正常了。

分析:

常规分析:

        通常情况下,这类问题无法分析,来的快去的快,日志中不会记录太多有效信息,但这次DBA同学在数据库hang住时把数据库运行堆栈打印保存了,这就有了分析根因的可能性。

        查看error log在hang住时间节点附近没有有效信息,慢查询记录也为空,查看监控发现当时写入insert非常高,这是slave机,写入来源于SQL线程回放,io利用率当时也跑满,但cpu也比较高,内存使用量在事发前后没有变化。如果简单的把这个故障归结到写入压力大,io资源不够,很难说的过去,压力大主从延迟变大可以理解,但是无法登陆数据库就不能解释了。

MySQL堆栈分析:

        由于有堆栈,进一步分析当时堆栈,整理如下:

         当时已经累积有753个尝试建立的连接的线程被卡住无法登陆,其它除sql线程外,都无明显异常。

        从堆栈上看,sql线程正在对一个分区表做insert数据,当时正在做内存申请操作,这就是比较诡异了,内存申请通常来说都是纳秒微秒级能完成的任务,这里居然能被打印出来,显然这个动作卡的时间比较长。

        查看一下内存使用率,当前MySQL进程居然占用了90%的内存,注意这是现在非故障时,现在没有业务流量,仅有几个复制线程在跑,而故障时作为读库有大量业务连接,内存占用量肯定更高。

        此时立马有个问题浮现:为什么mysqld进程没有OOM?查看一下规格,64c128G,如此强悍的机器,故障时还有富余内存,不至于OOM,但是这个内存使用率必然导致数据库进程在生死边缘挣扎了,同时也能解释为什么会卡在申请内存这了。

linux系统内存将耗尽时,大概会采取以下措施:

(1)系统内核会尝试通过回收不用的内存页(page)来为该进程分配内存。

(2)如果回收内存页后仍无法满足该进程的内存需求,Linux 内核会尝试通过交换空间(swap)来腾出更多的物理内存。

(3)如果交换空间不足以满足该进程的内存需求,Linux 内核会选择杀死某些进程来释放物理内存。

        数据库进程此时就处在第1-2阶段,而本机内存又比较大,操作系统进行这个过程可能比较慢,导致申请内存的线程一直在等,同样建立连接的线程也全需要申请内存,自然无法成功建立,但总体上运气不错,没有走到第3阶段就恢复了,mysqld没有被系统kill。

MySQL为什么会占如此多内存

        至此基本上确定了是内存不够,系统重分配慢所至,似乎可以至此为止了,但是这样的结论没有什么实际用处,下次业务高峰照样发生故障,所以有必要继续分析内存哪去了,是否可以避免再次故障。

那么内存去哪了?

  • buffer_pool 64G,减掉64G仍然有五六十G。

  • 当前没有业务连接,thread_pool_size才64,不会缓存太多线程,顶天不会超过1G。

  • table_open_cache、table_definition_cache 参数配的8192,看了下data目录,好家伙,3.9TB,并且全是分区表,9万多个ibd文件,那么这些表的缓存文件会占不少内存,可能会占到几个G。

  • 再加上其它一些其它内存,所有这些额外内存估计最多能占10多G,加上buffer pool内存后,总的往多算也就七八十GB。而当前没有业务连接的情况下,占用90%*128GB=115G,显然是不正常的。

难道是MySQL的内存泄漏bug?

        MySQL 5.1、5.5时代是存在一些内存泄漏bug的,但5.6开始极少了,5.7更是少之又少,目前没遇到过被证实的MySQL5.7内存泄漏bug。看再这个实例运行时间:900多天,要是mysqld本身有泄漏很难坚持这么久的。

         那么内存到底去哪了?直接给结论,这是glibc默认内存分配库ptmalloc的缺陷,有大量内存碎片无法被利用,导致进程内存使用量越来越大。那么是如何认定是该问题的?直接调gdb释放内存碎片命令看结果认定。

        直接执行:gdb -p 1793 -batch -ex 'call malloc_trim(0)'

        1793为mysqld进程,执行时可能会卡一两秒,但无其它影响,malloc_trim是专门用来释放内存碎片的,执行完之后内存占用情况:

 内存使用量瞬间从90%掉到62.5%,回到健康状态。

        该问题多年前首次在MySQL上遇到时,全过程花了数月才定位到,因为这个碎片内存涨的非常慢,导致定位分析周期长,像本次的案例就用了900多天才涨到这个量。

ptmalloc库缺陷介绍

        ptmalloc的这个缺陷也简单介绍下,不光MySQL,所有的用glibc内存库的c/c++程序都可能遇到,尤其多线程高并发长期运行的服务程序,一定有内存碎片,只是多少的区别。

        为了提高多线程并发情况下的内存分配效率,glibc 的ptmalloc维护了多个内存管理单元,每一个称作一个 arena,每个arena都使用 malloc_state来描述(malloc_state主要用于维护空闲的chunk 链表),只有main_arena 是通过 sbrk 来获得和管理内存的,其他arena是通过mmap 获取的;arena 可以包含多个heap,每个heap是通过mmap 获取的一个线性区,heap的最大大小是HEAP_MAX_SIZE(在64位系统是64M)。

        分配内存时,按照TLS(线程私有数据)中的arena –>main_arena ->arena1 ->arena2->… 的顺序进行遍历,依次进行trylock,如果 trylock成功,则在对应的arena中分配内存,若都不成功新建一个arena 来分配。

        当进程长期运行时,一个大内存块被不断被拆分成小碎片,这些小碎片内存会越来越多,也越来越难被重用,导致“内存泄漏”。

        另一方面,glibc的多线程运行也会带来一些问题,假设当前有3个arena,进程需要20kb内存,当前3个arena都有20kb的内存块,但是这些个arena都在使用中,try_lock加不上锁,此时进程就会增加一个arena来分配内存。同样假如arena2有符合要求的20kb内存块,但在arena1上try_lock成功,arena1又没有20kb的内存块,就会直接新分配一块挂在arena1上。总的来说,多线程下,存在原来的内存碎片无法利用反而去申请新的arena或者 heap的情况,导致内存碎片越来越多。

        想了解详细的可以找下相关glibc内存库相关的资料进行研究分析,参考文档:glibc内存管理ptmalloc源代码分析

总结与建议

  •  ptmalloc在多线程并发的情况下,容易产生内存碎片,日积月累容易占用大量不可利用内存,等同于内存泄露。

  • malloc_trim可以回收空闲碎片内存,对于长期内存高水位实例,可以定期(如按月)在业务低谷时执行。

  • 可以考虑更换mysql内存分配库,事实上,国内公有云mysql基本都用jemalloc代替了ptmalloc,除了能避免内存碎片问题,它的性能也好很多。

  • 另外,这个实例单库3.9T,近10万个数据文件,可以考虑优化一下空间。

一次 Java 进程 OOM 的排查分析(glibc 篇) 遇到了一个 glibc 导致的内存回收问题,查找原因和实验的的过程是比较有意思的,主要会涉及到下面这些: Linux 中典型的大量 64M 内存区域问题 glibc 的内存分配器 ptmalloc2 的底层原理 如何写一个自定义的 malloc hook 动态链接库 so glibc 的内存分配原理(Arena、Chunk 结构、bins 等) malloc_trim 对内存真正回收的影响 gd... 阅读详情

相关推荐

jvm堆外内存排查详解

内存泄漏想必大家并不陌生,对于jvm的内存泄漏,有很多排查手段和方便的排查工具,例如MAL,但是对于非jvm的内存,如直接内存的使用,排查起来较为麻烦,下面介绍一下相关的排查手段。

少说,多做 1万+

MySQL内存使用率高且不释放问题排查与总结

总结一下MySQL内存使用率高且不释放的应对方法: 继续加大内存(如果参数调无可调时选择); 修改减小innodb_buffer_pool_size参数(牺牲一定innodb性能); 排查消耗内存的慢SQL,及时优化; 检查相关session参数是否设置合理,比如join_buffer_size、query_cache_size是否设置过大; 使用gdb回收内存碎片(生产环境谨慎操作):gdb --batch --pid ‘pidof mysqld’--ex 'call malloc_trim(0)';

h363659487的博客 1万+

Debian 8 安装 Go 1.19:glibc 2.19 兼容性与 TLS 1.2 适配指南

Go 是一种静态强类型编译型语言,其二进制分发依赖底层 C 运行时(如 glibc)和系统网络栈(如 TLS 协议支持)。在老旧 Linux 发行版中,glibc 版本过低或内核缺失新系统调用,将导致 Go 1.20+ 无法运行;而 OpenSSL 1.0.1t 等旧库仅支持 TLS 1.0/1.1,与现代 Go 下载源强制 TLS 1.2+ 冲突。因此,Debian 8 这类 EOL 系统需精准选择 Go 1.19.x 分支——它在保持 glibc 2.19 兼容性的同时,规避了 getrandom()

526

JVM 调优之 glibc 引发的内存泄露

回顾上篇文章 JVM调优之G1换CMS 中 我们将 G1 换成 CMS 并调整了 JVM 参数,由于 GC 选择和参数设置的更加合理,所以内存的增长非常缓慢了。但这并没有从根本解决问题,通过观察发现,最高的时候一天 RSS 会增长 100M 左右,而且整体的趋势仍然是向上增长的,并没有一丝的回落迹象。问题分析虽然增长缓慢,哪怕每天只有 1M,离 OOM 也只是时间问题。这就使我们不得不再次仔细分析为什么 RSS 会一直增长。堆内存分析通过监控发现,堆内存呈周期性的增长和回收,与我们的 JVM 参数

m0_38017860的博客 1410

阿里云OpenClaw生产级部署:MySQL+Nacos+Ollama全链路实战

AI Agent运行时系统是现代智能应用的基础设施核心,其本质是以技能(Skill)为单元、数据库为记忆中枢、支持结构化输出的可扩展服务框架。部署关键在于多组件协同原理——MySQL保障元数据强一致性,Nacos实现配置动态治理,Ollama提供轻量模型推理能力,三者通过网络与资源隔离形成稳定底座。该技术组合具备高内聚、低耦合、易运维的工程价值,广泛适用于智能客服、自动化报表、竞品分析等企业级场景。本文聚焦阿里云ECS环境下的OpenClaw与Clawdbot真实落地,覆盖ESSD云盘选型、utf8mb4_

weixin_33970449的博客 519

Trae完整项目实战:Spring Boot+MySQL开发流配置指南

Trae并非传统IDE,而是一个可编程的开发会话引擎,其核心在于任务驱动、技能模块(Skills)协同与结构化上下文(Context)编排。理解Runtime Core调度机制、Skill进程隔离特性及Task+Context定义范式,是实现Java工程闭环的关键。本文聚焦Spring Boot完整项目落地,涵盖maven-skill环境适配、springboot-skill启动流程、mysql-mcp-skill数据库集成等真实场景,解决‘系统未知错误’、parent POM解析失败、IPC socket

444

MySQL概述(GLIBC方式安装)

目录:一、MySQL概述1.关系型数据库和非关系型数据库:2.常见的关系型数据库:3.什么是事务:4.事务特性:二、获取mysql软件2.源码编译版本:3.三种安装方式的对比:三、区分数据库和数据库实例四、数据库的安装1.GLIBC方式安装: 一、MySQL概述 1.关系型数据库和非关系型数据库: RDBMS(relational database management system)即关系型数据库管理系统。简单来说关系型数据库,是指采用了二维表格来组织数据的数据库 扩展:数据库在行业内一般有两种情况

qq_44944641的博客 2617

MySQL安装失败十大原因与系统排查指南:从权限到残留的完整解决方案

关系型数据库的部署与运维是后端开发和系统管理中的基础技能,其核心在于理解数据库服务与操作系统的深度集成原理。在安装过程中,权限管理、端口冲突、服务残留和依赖库完整性等技术环节直接影响部署成功率。掌握系统性的故障排查方法具有重要技术价值,能有效提升运维效率和系统稳定性,尤其适用于开发环境搭建、测试部署和生产服务器配置等场景。本文聚焦MySQL安装过程中的常见陷阱,针对**服务残留**和**端口冲突**等高频问题,提供从诊断到解决的完整链路,帮助开发者快速定位并解决安装障碍。

dengjuanshou7445的博客 382

Ubuntu 14.04 MySQL 5.5 安装配置实战指南

MySQL 是一种关系型数据库管理系统,其核心原理依赖于客户端-服务器架构、ACID 事务机制与 SQL 查询引擎。在老旧 Linux 发行版中,MySQL 的技术价值体现为对遗留业务系统的底层支撑能力——尤其在 ABI 兼容性、初始化系统(upstart)适配和 glibc/OpenSSL 版本约束下,版本对齐比功能先进性更重要。典型应用场景包括工业数据采集终端、嵌入式网关及传统 ERP 系统维护,这些环境普遍面临 apt 源失效、AppArmor 权限拦截、mysql_secure_installati

754

CentOS VPS部署Zenoss 4.6.5实战:老旧监控系统与现代Linux的兼容适配

Zenoss作为典型的遗留企业级Python监控系统,其核心依赖Zope框架、MySQL 5.6及RRDtool存储,代表了一类强耦合、低容器化适配度的传统运维工具。理解其基于事件驱动架构的设计原理,有助于把握老旧监控系统在云环境中的技术价值——尤其在教育网管、中小IDC等需长期稳定运行的场景中,它提供比Zabbix更细粒度的设备建模能力,又比Prometheus更少依赖Kubernetes生态。本文聚焦CentOS 7.9 Minimal环境下Zenoss Core 4.6.5的完整部署链路,覆盖Zope

weixin_30363509的博客 433

MySQL BLOB存图片的实战决策指南:Ubuntu 20.04 + PHP深度避坑

BLOB(Binary Large Object)是关系型数据库中存储二进制大对象的基础机制,其核心原理在于将文件数据作为字段值嵌入事务引擎(如InnoDB),从而保障ACID一致性与备份原子性。相比文件路径引用,BLOB的技术价值体现在强事务绑定、权限统一管控、分布式路径解耦及运维收敛性,但代价是显著增加磁盘IO、内存压力与网络传输开销。典型应用场景包括金融开户凭证、医疗影像元数据、政务审批附件等对数据不可分割性有硬性合规要求的系统。本文聚焦Ubuntu 20.04环境下PHP与MySQL协同操作BLOB

weixin_30873847的博客 443

Qt 5.14.2 aarch64静态交叉编译实战指南

Qt静态编译是一种将Qt库与应用程序代码全量链接为单个可执行文件的技术,其核心原理是通过静态链接替代动态加载,消除运行时对.so共享库的依赖。该技术在信创、工控、嵌入式等强稳定性场景中具备关键价值,可实现零依赖部署、确定性启动与高环境兼容性。典型应用场景包括国产ARM平台(如鲲鹏、飞腾、瑞芯微)上的工业监控软件、边缘网关GUI程序及银河麒麟/统信UOS系统的离线交付。本文聚焦Qt 5.14.2与aarch64架构的深度适配,系统解决静态交叉编译中的glibc版本兼容、Qt源码补丁、交叉工具链定制等硬性问题,

weixin_33851429的博客 314

M系列Mac部署达梦DM8:UTM+OpenEuler ARM64实战指南

ARM64架构已成为国产数据库适配的关键技术底座,而达梦DM8作为深度支持ARM64的工业级数据库,其在Apple Silicon平台的落地需突破指令集、ABI兼容与虚拟化层三重约束。UTM凭借对Hypervisor.framework的原生调用,实现零转译的ARM64 Linux虚拟化;OpenEuler 22.03 LTS SP3则因内核参数、glibc版本及SELinux策略与达梦官方编译环境严格对齐,构成最小可行运行环境(MVE)。该方案广泛应用于开发测试、信创教学及轻量POC场景,为macOS用户

weixin_34354945的博客 335

MySQL实战部署与排障:从裸机安装到ERROR 2002定位

MySQL是后端开发与DBA岗位的核心数据库系统,其服务启停、客户端连接、权限配置及错误排查构成基础工程能力。理解mysqld.service生命周期、socket与TCP连接机制、SSL握手流程及认证插件兼容性,是解决ERROR 2002、SSL connection error等高频问题的关键。技术价值在于打通Linux环境下的完整交付闭环——从离线rpm安装、Docker容器化部署,到Navicat/Java应用连接调优。典型应用场景包括国产操作系统适配(如麒麟V10)、云下自建高可用架构、遗留系统迁

weixin_34357436的博客 300

Ubuntu 18.04 安装 Ansible 的三种生产级方案与兼容性避坑指南

Ansible 是基于 SSH 和 Python 的无代理自动化运维工具,其核心原理是通过 YAML 描述声明式任务,由控制节点调用模块在被管主机上执行。技术价值在于轻量、安全、易审计,特别适合中小团队和 DevOps 初学者。典型应用场景包括批量部署 Nginx、配置防火墙、同步证书及用户密钥管理。但在 Ubuntu 18.04 这类已进入 ESM 维护阶段的系统中,面临 Python 2.7/3.6 混合环境、系统 pip 版本过旧、cryptography 编译失败、sudo 权限提示超时等真实兼容性

weixin_34122810的博客 344

Ubuntu交叉编译Jetson arm64程序实战指南

交叉编译是嵌入式Linux开发的基础技术,指在x86_64主机上生成ARM64目标平台可执行文件,其核心原理在于分离编译时环境(host)与运行时环境(target),解决资源受限设备(如Jetson)本地构建效率低、内存溢出、温度过高及ABI不兼容等工程瓶颈。该技术具备显著技术价值:提升编译速度5–10倍、减小二进制体积、保障CUDA/VPI等专有API符号一致性,并支撑CI/CD自动化部署。典型应用场景包括机器人SLAM节点、边缘AI推理服务、工业视觉应用等需面向NVIDIA Jetson系列(Orin

weixin_34211761的博客 353

Ubuntu 14.04 MySQL 5.5.62 安装与生产级配置指南

MySQL 是广泛使用的开源关系型数据库管理系统,其安装与配置需兼顾系统兼容性、安全加固与资源约束。在老旧但仍在服役的 Ubuntu 14.04 环境中,官方支持虽已终止,但大量工业设备、边缘终端和教育系统仍依赖该平台运行关键业务。此时,选择 ABI 稳定、内存占用低的 MySQL 5.5.62 版本,并通过原生 apt 源安装配合精细化 my.cnf 调优,成为保障服务可用性的技术共识。该方案规避了 Docker 兼容性问题、手动编译的 GCC/libstdc++ 陷阱以及第三方源失效风险,特别适用于 2

weixin_33778544的博客 487

Ubuntu 18.04下Laravel容器化实战:Docker Compose与volumes深度配置

容器化是现代PHP应用环境标准化的核心手段,其本质是通过声明式配置实现开发、测试与生产环境的一致性契约。基于Linux发行版的容器运行时依赖内核特性(如cgroups、namespaces)与用户空间工具链(glibc、systemd)协同工作;Docker Compose作为编排层,通过服务定义、网络隔离和卷挂载机制,将Laravel的文件系统敏感性(storage日志、缓存、.env)、进程模型(php-fpm+nginx分离)及调试需求(Xdebug主机发现)转化为可复现的工程实践。其中volumes

aodan5477的博客 484
上一篇: MySQL truncate导致慢查询根因竟然是“多此一举”
下一篇: 聊聊几个MySQL“老生常被喷”点
postgres20
博客等级 码龄10年 100粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值