故障分析 | MySQL OOM 故障应如何下手

Rancher入门到精通- docker配置调优 日志设置 touch /etc/docker/daemon.json cat > /etc/docker/daemon.json <<EOF { "oom-score-adjust": -1000, "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "max-concurrent-downloads": 10, "max-co. 阅读详情

作者:孙祚龙
爱可生南区分公司交付服务部成员,实习工程师。负责公司产品问题排查及日常运维工作。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


引言

前阵子处理这样一个案例,某客户的实例 mysqld 进程内存经常持续增加导致最终被 OOM killer。作为 DBA 肯定想知道有哪些原因可能会导致 OOM(内存溢出)。

此篇文章叙述个人的一些拙见~

先介绍下这位朋友:OOM-killer

OOM Killer(Out of Memory Killer) 是当系统内存严重不足时 linux 内核采用的杀掉进程,释放内存的机制。

OOM Killer 通过检查所有正在运行的进程,然后根据自己的算法给每个进程一个 badness 分数,拥有最高 badness 分数的进程将会在内存不足时被杀掉。

它打分的算法如下:

  • 某一个进程和它所有的子进程都占用了很多内存的将会打一个高分。

  • 为了释放足够的内存来解决这种情况,将杀死最少数量的进程(最好是一个进程)。

  • 内核进程和其他较重要的进程会被打成相对较低的分。

上面打分的标准意味着,当 OOM killer 选择杀死的进程时,将选择一个使用大量内存,有很多子进程且不是系统进程的进程。

简单来讲,oom-killer 的原则就是损失最小、收益最大,因此它会让杀死的进程数尽可能小、释放的内存尽可能大。在数据库服务器上,MySQL 被分配的内存一般不会小,因此容易成为 oom-killer 选择的对象。

“既然发生了 OOM,那必然是内存不足,内存不足这个问题产生原因很多。

首先第一个就是 MySQL 自身内存的规划有问题,这就涉及到 mysql 相应的配置参数。

另一个可以想到的原因就是一般部署 MySQL 的服务器,都会部署很多的监控和定时任务脚本,而这些脚本往往缺少必要的内存限制,导致在高峰期的时候占用大量的内存,导致触发 Linux 的 oom-killer 机制,最终 MySQL 无辜躺枪牺牲。”

all-important:MySQL 自身内存规划

说到 MySQL 自身的内存规划,最先想到的就是 MySQL 中各种 buffer 的大小,innodb buffer pool 就是最鹤立鸡群的那个。innodb_buffer_pool_size 参数的大小究竟如何设置,才能保证 MySQL 的性能呢?在官网文档中可以找到这个参数的一些描述:

A larger buffer pool requires less disk I/O to access the same table data more than once. On a dedicated database server, you might set the buffer pool size to 80% of the machine’s physical memory size.

意思是在专用数据库服务器上,可以将 innodb_buffer_pool_size 设置为计算机物理内存大小的 80%。在许许多多前辈的的经验中了解到,此参数的值设置为物理内存的 50%~80% 颇为合理。

举个栗子:

innodb buffer pool 分配 76G,每个连接线程最大可用 160M,最大有 3000 连接数,最大可能使用内存总量 545G,但是这台实例所在服务器的物理内存仅仅有 97G,远超物理内存总量。结果可想而知,这个实例在运行中经常被 oom-killer 杀死,想必原因之一即是因为一开始 MySQL 自身的内存规划欠妥。

innodb buffer pool 缓存数据的作用相信大家都懂,比如这个 case 中,可以发现该实例为写密集,读请求很少,innodb buffer 对性能改善作用不大,80% 的内存没必要,完全可以降低到物理内存的50%。

“ 以上是对 OOM 发生原因的一些见解,那思考一下还有没有其他的原因会导致内存溢出的情况呢?不知道大家对内存泄漏是否了解,有没有可能 MySQL 因为内存泄漏堆积演变为内存溢出,最终 oom-killer … ”

知识补给站:内存泄漏

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

内存泄漏缺陷具有隐蔽性、积累性的特征,比其他内存非法访问错误更难检测。因为内存泄漏的产生原因是内存块未被释放,属于遗漏型缺陷而不是过错型缺陷。此外,内存泄漏通常不会直接产生可观察的错误症状,而是逐渐积累,降低系统整体性能,极端的情况下可能使系统崩溃。

上文说到内存泄漏具有隐蔽性,就是不容易被发现呗…为之奈何?
那咱们就去找一个可以检测内存泄漏的工具:valgrind

关于 valgrind 工具

Valgrind 是一个用于构建动态分析工具的工具框架。它提供了一组工具,每个工具都执行某种调试、分析或类似的任务,以帮助您改进程序。Valgrind 的体系结构是模块化的,因此可以轻松地创建新工具,而不会影响现有的结构。

标配了许多有用的工具:

  1. Memcheck 是内存错误检测器。

  2. Cachegrind 是一个缓存和分支预测探查器。

  3. Callgrind 是一个生成调用图的缓存分析器。

  4. Helgrind 是线程错误检测器。

  5. DRD 还是线程错误检测器。

  6. Massif 是堆分析器。

  7. DHAT 是另一种堆分析器。

  8. SGcheck 是一种实验性工具,可以检测堆栈和全局阵列的溢出。

  9. BBV 是一个实验性 SimPoint 基本块矢量生成器。

关于内存泄漏,我们需要使用 valgrind 的默认工具,也就是 memcheck 工具。

Memcheck 是内存错误检测器。它可以检测以下和内存相关的问题:

  • 使用未初始化的内存

  • 读取/写入已释放的内存

  • 读取/写入 malloc 块的末端

  • 内存泄漏

  • 对 malloc/new/new[]与free/delete/delete[] 的不匹配使用

  • 双重释放内存

Valgrind Memcheck 工具的用法如下:

valgrind --tool=memcheck ./a.out

从上面的命令可以清楚地看到,主要的命令是“ Valgrind”,而我们要使用的工具由选项“ --tool”指定。上面的“ a.out ” 表示我们要在其上运行 memcheck 的可执行文件。此外还可以使用其他的命令行选项,以满足我们的需要。运行的程序结束后,会生成这个进程的内存分析报告。

“ OK,工具有了,这就如同摸金校尉拿到了洛阳铲,宝藏还会远吗~ 还不快找几块地挖掘试试?”

搞个测试找找感觉

  1. 使用 valgrind 的 memcheck 工具启动 mysql:
valgrind --tool=memcheck --leak-check=full --show-reachable=yes --log-file=/tmp/valgrind-mysql.log /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --user=root
  1. 利用 sysbench 模拟负载;

  2. 进程结束后查看检测报告:

==29326== LEAK SUMMARY:
==29326==    definitely lost: 0 bytes in 0 blocks
==29326==    indirectly lost: 0 bytes in 0 blocks
==29326==      possibly lost: 549,072 bytes in 1,727 blocks
==29326==    still reachable: 446,492,944 bytes in 54 blocks
==29326==         suppressed: 0 bytes in 0 blocks
==29326==
==29326== For counts of detected and suppressed errors, rerun with: -v
==29326== ERROR SUMMARY: 339 errors from 339 contexts (suppressed: 0 from 0)

在报告的最后的总结中发现程序退出时有部分内存未释放,而且存在潜在的内存泄漏。通过向上查看具体的信息,分析后发现主要集中在 performance_schema,偶然发现了一个疑点,那我们完全禁用掉 performance_schema 呢?

==9954== LEAK SUMMARY:
==9954==    definitely lost: 0 bytes in 0 blocks
==9954==    indirectly lost: 0 bytes in 0 blocks
==9954==    possibly lost: 0 bytes in 0 blocks
==9954==    still reachable: 32 bytes in 1 blocks
==9954==         suppressed: 0 bytes in 0 blocks
==9954==
==9954== For counts of detected and suppressed errors, rerun with: -v
==9954== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

发现程序退出时几乎没有内存未释放,也不存在潜在的内存泄漏。三次测试过后,发现结果是一致的。这是什么原因?

“ 大家都知道 MySQL 的 performance schema 用于监控 MySQL server 在一个较低级别的运行过程中的资源消耗、资源等待等情况,但它为什么可能会导致内存泄漏呢,看来关于 ps 还有不少待挖掘的宝藏哦~ ”

最后一个小总结

  1. 注意 MySQL 自身的内存规划,为保证 MySQL 的性能,innodb buffer pool 大小设置要合理,可以根据实例读写负载的情况适当调整 buffer pool 的大小。并且 innodb buffer 与连接会话内存的总和尽量不要超过系统物理内存。

  2. 调整 oom_score_adj 参数(/proc//oom_score_adj),将 MySQL 被 oom-killer 锁定的优先级降低。这个参数值越小,越不容易被锁定。

  3. 加强内存的监控和报警,一旦报警,DBA 应该迅速介入,选择性 Kill 掉一些占用较多内存的连接。

  4. 在开启 performance_schema 时,会有额外的内存开销,通过 valgrind-memcheck 内存分析工具发现,较大概率发生内存泄漏。它有可能也会导致 OOM,在场景中若不需要 performance_schema 可以完全禁用,或需要尽量只开启必要的 instrument。

Docker daemon 文件配置 { "oom-score-adjust": -1000, "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "max-concurrent-downloads": 10, "max-concurrent-uploads": 10, "bip": "192.168.1.1/24", "registry-mirrors": ... 阅读详情

相关推荐

深空探测处理软件USGS-ISIS的下载安装

深空探测处理软件USGS-ISIS下载安装教程

qq_31721595的博客 3311

如何调整Linux中的OOM Killer行为

在Linux系统中,当系统的内存资源耗尽时,内核会触发“Out of Memory”(简称OOM)机制来尝试回收内存,通常是通过终止占用大量内存的进程。虽然关闭OOM Killer是不可能的,因为它是内核的一部分,但可以通过调整相关内核参数来改变其行为。本文将介绍两种方法来调整OOM Killer的行为。

三问Linux社区 1076

手把手教你用WKT文件在Petrel中创建自定义坐标系统(附CGCS2000转换模板)

本文详细介绍了如何在Petrel软件中利用WKT文件创建自定义坐标系统,并重点提供了CGCS2000坐标系的完整转换模板与实战步骤。通过解析坐标系统的三大支柱(大地坐标系、投影坐标系、基准转换)和WKT文件结构,指导用户从零开始构建适用于本土化项目的坐标系统,确保地质建模与空间数据处理的精度与一致性。

gpt4scribbler的博客 277

k8s oom

这段代码就是讲的如何计算每个容器的oom score的。 首先看这个容器所属的Pod是属于什么级别的,如果是Guaranteed级别的直接返回-998也是最高级最后被Kill掉的,如果是BestEffort级别则直接返回1000是最低级别的,最有可能被杀掉。如果是Burstable则是中间级别需要按照资源的申请量来计算oom score。 oomScoreAdjust := 1000 - (1...

wasd12121212的博客 1207

基于YOLOv8和PaddlepaddleOCR的微信截图聊天记录提取

本文提出了一种基于YOLOv8和PaddleOCR的微信聊天记录提取方法。首先使用YOLOv8n模型分割出聊天气泡(针对深浅色模式分别训练),通过合成数据集增强模型鲁棒性,召回率达0.995。随后采用PP-OCRv5进行文本识别,利用坐标匹配将气泡内文本送入识别队列,短长文本平均置信度分别>0.98和>0.95。文中特别强调了PaddleOCR不同版本的输出格式差异及适配方案,建议使用3.0+版本。该方法有效解决了直接OCR识别易受干扰的问题,通过气泡分割+文本定位的两阶段策略显著提升了识别准确

2401_87383958的博客 2354

fluent linux运行算例,Fluent算例精选|03利用VOF和蒸发-冷凝模型

通过学习本算例您将获得?1、学会基本的VOF模型设置流程2、学会利用蒸发-冷凝模型来模拟传热沸腾目录1摘要42传热沸腾模型介绍43前处理44求解设置54.1启动Fluent54.2网格缩放64.3求解器设置74.4多相流模型设置84.5能量方程求解设置94.6紊流模型设置104.7添加材料114.8多相流中相设置124.9操作条件设置144.10边界条件设置154.10.1heatsource边界...

weixin_33278819的博客 3186

记一次莫名停服(OOM Killer)

早上发现网站无法访问,查看状态码,是502,即知道是负载后端的应用停服。登录服务器,进程确认已经不存在。检查应用日志,却发现并无异常,很奇怪进程为啥会挂掉。 查看 /var/log/message 发现如下信息: Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name ...... Jun 28 16:08:55 iZ8vbxxx1u3Z ke

Sarah Cla的专栏 4323

西门子1200之PID用法与控制

西门子PID加热试验

gyxgyx789的博客 6254

故障分析 | 奇怪!内存明明够用,MySQL 却出现了 OOM

作者:刘开洋 爱可生交付服务部团队北京 DBA,主要负责处理 MySQL 的 troubleshooting 和我司自研数据库自动化管理平台 DMP 的日常运维问题,对数据库及周边技术有浓厚的学习兴趣,喜欢看书,追求技术。 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 问题 前几天遇到一个奇怪的问题,服务器内存明明够用,结果在对 MySQL 进行测压的时候却出现了 OOM,是 Linux 内核出错了吗? 具体现象如下:使用 sysbench 对 my.

ActionTech的博客 1312

GJB 5000B二级-II实施基础

本文主要描述GJB 5000B二级II实施基础与GJB 5000A的变化情况,以及过程域各条款的实施要点

Abel的博客 2581

RK3576 PCIE接口调试:基于RTL8111HS的网卡驱动移植

检查项方法电源电压复位时序检查设备树 reset-gpios链路速率设备识别lspci -vvv驱动加载。

小灰灰的博客 731

mysql缓解oom发生的方法_OOM导致MySQL服务被kill案例一则

看到这个故障分析 | MySQL OOM 故障应如何下手,想起来几天前也遇到一次MySQL服务因为OOM被杀掉的情况,记录一下背景:一个测试环境,由于Centos系统上没有设置虚拟内存,运行的MySQL实例buffer_pool_size配置的不合理,运行了一个较大的查询后,产生了一个戏剧性的问题。现象:前端工具执行某个sql,一点击执行,过几秒钟连接客户端显式断开MySQL连接,第一次没在意,以...

weixin_42430341的博客 547

30天入门 SAP BTP 开发系列之八:动手在 SAP BTP 上开发第一个 ABAP 透明表

ABAP Cloud 环境下创建透明表的方法与数据迁移实践 本文介绍了在 SAP BTP ABAP 环境中创建透明表并迁移数据的完整流程。与传统的 SE11 事务码不同,ABAP Cloud 需通过 ABAP Development Tool 创建数据库表,使用代码定义表结构。作者详细演示了如何: 在开发包中创建名为 Z优快云_TRAVEL 的透明表 使用 ABAP 代码定义表字段和约束 通过 ABAP 类实现数据从标准表/DMO/TRAVEL 到新建表的迁移 验证数据迁移结果 文中还提供了相关技术概念的

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1785

oom异常 php,故障分析 | 奇怪!内存明明够用,MySQL 却出现了 OOM

作者:刘开洋爱可生交付服务部团队北京 DBA,主要负责处理 MySQL 的 troubleshooting 和我司自研数据库自动化管理平台 DMP 的日常运维问题,对数据库及周边技术有浓厚的学习兴趣,喜欢看书,追求技术。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。问题前几天遇到一个奇怪的问题,服务器内存明明够用,结果在对 MySQL 进行测压的时...

weixin_39843677的博客 518

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

MySQL数据库OOM故障报告

MySQL数据库OOM故障报告 故障描述 2017年5月23日10:43分,MySQL生产库...

cjfcxf010101的博客 599

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

一次MySQL5.7线上故障分析

一次MySQL5.7线上故障分析 原创 2017-01-03 邹宇 ACMUG ACMUG征集原创技术文章。详情请添加 A_CMUG或者扫描文末二维码关注我们的微信公众号。有奖征稿,请发送稿件至:acmug@acmug.com。 3306现金有奖征稿说明:知识无价,劳动有偿,ACMUG特约撰稿人有奖回报计划(修订版) 作者简介:邹宇 邹宇,滴滴出行

渔夫数据库笔记 1553

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

后端线上故障分析与实战避坑案例

《后端线上故障分析与实战避坑案例》摘要: 本文剖析了分布式系统中的典型故障场景,包括电商超卖、重复扣款等P0级事故。通过真实案例揭示了Spring事务与分布式锁的时序错位、读写非原子操作等隐藏风险,提出编程式事务边界控制、唯一索引防重等解决方案。同时对比分析了幂等性八大实现方案的适用场景与局限性,并探讨了容器环境下CPU资源调度的常见陷阱。为架构师提供了从代码层到基础设施层的全链路避坑指南,强调通过事务隔离、锁生命周期管理和资源配额控制构建反脆弱系统。

1586

故障分析 | MySQL 耗尽主机内存一例分析

开发人员反馈,有一台服务器内存几乎被 MySQL 耗尽了,执行 top 命令,输出如下:这台机器是个测试环境,MySQL 是开发自己安装的,数据库版本 5.6.51 ,机器总内存32G,MySQL 占了29G。查看 MySQL 启动时间发现1个星期前才启动,猜测之前由于主机内存耗尽触发了 OOM ,查看 MySQL 错误日志,发现每隔10几天,MySQL 就异常关闭一次: 查看操作系统日志,进一步验证了 MySQL 耗尽主机内存,触发 OOM : 查看 my.cnf 配置文件,发现几乎都是默认配置,inno

ActionTech的博客 867

MySQL 全文索引触发 OOM 一例

线上 MySQL 都是使用 Tcmalloc 内存分配器一直很稳定,并未出现服务器内存不足问题。本次出现服务器内存不足,是因为使用了全文索引这种极少使用的场景触发,换成 Jemalloc 后,内存使用整体上得到了控制。

ActionTech的博客 748

MySQL故障:从Hang到Crash的深度解析

该故障本质是。

568

(基础)MySQL 故障分析 需要抽取那些信息

背景 数据库故障时的处理步骤 写在前面 (推荐阅读)原文链接https://www.modb.pro/db/41601 link 采集信息,进行分析问题。问题包括: TPS突然下降到 0 连接数直接爆满 error日志无记录 突然hang住 数据库服务不停的重启 内存曲线是上升,最后OOM 操作 监控,日志优先 1.基础信息包含OS信息,mysql版本,高可用,参数设置 mysql -uroot -p -S /tmp/mysql.sock -e "\s;show global variables;

一杯Mojito可以吗 245

mysql突然出现大量慢sql,随后redis访问超时

在亚马逊云买了多台的虚拟主机,一年多没有由于系统的原因出过故障。今天碰见了。 早上接到报警,从业务故障上来看,应该是数据库没有响应了。 SSH连数据库服务器,发现连不上。 重启数据库服务器,一直起不来。 最后用上周的数据库服务器的系统备份snapshot(我们的数据盘和系统盘是分开的)新建一个Volume,替换掉故障系统盘,重新启动服务器,才顺利进入系统。在用新的Volume挂靠服务器的...

黄湘龙的技术博客 504

VM 软锁死(Soft Lockup)故障分析报告

startuml 决策树startif (系统卡死, dmesg 有 soft lockup?) then (是):top 查看 CPU 状态;if (si 高 > 50%?) then (是):内存不足导致 I/O 链式反应;:扩大 VM 内存;else (否)if (idle 高 > 50%?) then (是):空闲时卡死, TSC 时钟源问题;:切换 acpi_pm;else (否)if (steal 高 > 10%?) then (是):宿主机超售;

qq_35159351的博客 392

【20年Linux运维架构师总结】系统故障分析和排查001

先观测(监控+日志)→定位(缩小范围)→分析(根因)→修复。优先恢复业务(如切换节点)再深入分析。事后复盘,优化架构和监控,防止同类故障再次发生。掌握这些方法和工具,能有效提升系统稳定性,减少故障恢复时间!🚀。

老韩的Linux云计算架构师进阶之路 997

数据库周刊50丨12月国产数据库排行;瀚高软件荣获“2020中国年度最佳雇主”;TiDB推出耗时关系图;Oracle 21c 新特性;MySQL故障分析信息提取;排查PG请求超时;DM8全文索引……

热门资讯 1、2020年12月国产数据库排行:榜首TiDB 2.7亿融资再破纪录;openGauss晋级十强! 【摘要】2020年12月份国产数据库排行榜已发布。前三名依旧分别是TiDB、达梦数据库、GBase(南大通用),第4-6名,分别是 OceanBase、PorlarDB、TDSQL。本月,GaussDB与TBase排位互换,GaussDB位于第7位,TBase位于第8位,GoldenDB与openGauss均前进一位,分别排行第九和第十,SequoiaDB以2分之差无缘前十。 2、云和恩墨Mog.

ToyaAkira00的博客 859

MySQL 崩溃之谜:一条 SELECT 查询引发的内存地址错乱

本文深入剖析了一起由SELECT查询引发的MySQL数据库崩溃案例。通过分析错误日志中的SIGSEGV信号和堆栈信息,定位到问题源于优化器将EXISTS子查询转换为Semi-join DuplicateWeedout策略时,内部出现空指针访问。文章提供了从紧急规避到彻底升级的完整故障分析与解决方案,并分享了专业的数据库故障排查方法论。

php55的博客 896
上一篇: 第09问:MySQL 莫名崩溃,如何保留现场?
下一篇: 第01期:详解 Prometheu 专栏开篇
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值