一个月之前,Scott和同事们发现公司有一个MySQL MHA集群的master(假设master机器名为hostA)每隔一周左右就会挂一次(指MySQL挂掉),在几周内,MHA来回切了好几次。

按照国际惯例,Scott按照如下顺序去查问题到底出在哪里:
(1)先翻MySQL error log,没有发现异常
(2)再翻Linux系统日志文件,果然,翻到了下面的内容:

Nov 26 13:05:38 hostA kernel: mysql invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0
...此处内容省略N行...
Nov 26 13:05:38 hostA kernel: Out of memory: Kill process 32271 (mysqld) score 976 or sacrifice child
Nov 26 13:05:38 hostA kernel: Killed process 32271, UID 496, (mysqld) total-vm:83064212kB, anon-rss:64204132kB, file-rss:4544kB

该机器的物理内存大小为62G,从上面的日志看,MySQL确实已经把它用满了。该机器上MySQL的innodb_buffer_pool=31G,Scott认为这已经相当保守了,而且各种buffer_size我们都使用的是默认值,MySQL OOM时的用户连接数是100+,

这些目测都没有什么问题,但是居然还是发生了OOM,实在是不可思议。当时觉得就是内存不够用了呗,没有查出具体原因,后来62G的内存加到了125G(innodb_buffer_pool_size增大到64G,这值确实很保守),还是发生了OOM。(OOM指的是在系统物理内存被用完时,Linux内核为了保证系统的正常运行,根据一定的算法杀掉占用内存较大的进程,基本上可以认为是杀掉占用内存最大的进程以释放内存资源。)

其实一开始Scott就发现,这台机器上有一个更早的问题,就是因为系统最大文件打开数不够导致这台机器的xtrabackup备份总是不成功,具体是什么原因请等Scott去整理xtrabackup备份的更详细的过程。然后我去检查了该机器上面的*.ibd文件和*.frm文件数量,吓我一跳:

[userA@hostA mysql]$ sudo find . -name '*.ibd' | wc -l
169577
[userA@hostA mysql]$ sudo find . -name '*.frm' | wc -l
2534

也就是说,该机器上面竟然有17万个ibd文件,但是只有2534张表,很明显是分区表中的分区数量非常多。

[userA@hostA mysql]$ sudo find . -name '*par*' | wc -l
1882

Scott仔细比较了这台机器和其他没有问题的机器的不同,发现这台机器上面分区数量太多是唯一的一个不同,这让Scott没有办法不怀疑是分区导致的问题。

Scott仍然按照国际惯例,第一时间去查MySQL 5.6的官方文档,无果。。。(官方文档虽然不是万能的,但是仍然是出现问题的第一参考资料)

去MySQL的bugs页面搜索关于partition的bug,无果。。。

去google了下,发现有的比较杂的网站上面写道MySQL分区数量太多引发内存耗尽的问题,但是文章讲的内容感觉不是很正确。

最后在姜老师的指点下,看了这篇文章:

http://mysqlserverteam.com/innodb-native-partitioning-early-access/

上面是MySQL开发团队写的关于InnoDB Native Partitioning的文章。文章中大概讲的内容是,在5.6里面,分区的信息是在MySQL Server层维护的(在.par文件里面),InnoDB引擎层是不知道有分区这个概念的,InnoDB引擎层把每一个分区都当成一张普通的InnoDB表。在打开一个分区表时,会打开很多个分区,打开这些分区表就相当于打开了同等数量的InnoDB表,这需要更多内存存放InnoDB表的元数据和各种与ibd文件打开相关的各种cache与handler的信息。在5.7里面,InnoDB引入了Native Partitioning,它把分区的信息从Server层移到了InnoDB层,打开一个分区表和打开一个InnoDB表的内存开销基本是一样的。

If we compare the amount of memory used when opening a single instance of this table, first using the old generic non-native partitioning, and then with InnoDB Native Partitioning we see the following:

One open instance of the table takes 49% less memory (111MB vs 218MB) with the current state of Native Partitioning support. With ten open instances of the table, we take up 90% less memory (113MB vs 1166MB)!

由于升级到5.7还需要一些时日,目前已经将分区数量减少到25000,125G剩余内存在20天里一直稳定在20G左右,这也表明确实是分区数量太多的原因。

5.6 太多分区引起OOM的更多相关文章

  1. 什么是hive的静态分区和动态分区,它们又有什么区别呢?hive动态分区详解

    面试官问我,什么是hive的静态分区和动态分区,这题我会呀. 简述 分区是hive存放数据的一种方式,将列值作为目录来存放数据,就是一个分区,可以有多列. 这样查询时使用分区列进行过滤,只需根据列值直 ...

  2. Linux学习(CentOS-7)---磁盘分区(概念、分区方法、分区方案)

    1磁盘分区相关的概念 1.1什么是磁盘 磁盘就是计算机的外部存储器设备,即将圆形的磁性盘片装在一个方的密封盒子里,这样做的目的是为了防止磁盘表面划伤,导致数据丢失.简单地讲,就是一种计算机信息载体,也 ...

  3. Spark排错与优化

    一. 运维 1. Master挂掉,standby重启也失效 Master默认使用512M内存,当集群中运行的任务特别多时,就会挂掉,原因是master会读取每个task的event log日志去生成 ...

  4. [转帖]Docker容器CPU、memory资源限制

    Docker容器CPU.memory资源限制 https://www.cnblogs.com/zhuochong/p/9728383.html 处理事项内容等 这一块内容感觉 不清楚.. 背景 在使用 ...

  5. Docker(二十)-Docker容器CPU、memory资源限制

    背景 在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU.内存和磁盘资源.如果不 ...

  6. [转] - Spark排错与优化

    Spark排错与优化 http://blog.csdn.net/lsshlsw/article/details/49155087 一. 运维 1. Master挂掉,standby重启也失效 Mast ...

  7. Spark实践 -- 性能优化基础

    性能调优相关的原理讲解.经验总结: 掌握一整套Spark企业级性能调优解决方案:而不只是简单的一些性能调优技巧. 针对写好的spark作业,实施一整套数据倾斜解决方案:实际经验中积累的数据倾斜现象的表 ...

  8. Docker容器CPU、memory资源限制

    背景 在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU.内存和磁盘资源.如果不 ...

  9. Docker运行时资源限制

    Docker 运行时资源限制Docker 基于 Linux 内核提供的 cgroups 功能,可以限制容器在运行时使用到的资源,比如内存.CPU.块 I/O.网络等. 内存限制概述Docker 提供的 ...

随机推荐

  1. (转载)有关反演和gcd

    tips : 积性函数 F (n) = Π F (piai ) 若F (n), G (n)是积性函数则 F (n) * G (n) Σd | n F (n) 是积性函数 n = Σd | n  φ ( ...

  2. Java [leetcode 23]Merge k Sorted Lists

    题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complex ...

  3. 【原】android通过adb wireless的使用

    开发android程序,总是需要插拔插拔的,usb口都给弄坏掉了,现在adb可以通过无线网,链接处在同一个局域网下面的android设备 1.将电脑和移动设备链接到同一个无线网下 2.在android ...

  4. 线性表-串:KMP模式匹配算法

    一.简单模式匹配算法(略,逐字符比较即可) 二.KMP模式匹配算法 next数组:j为字符序号,从1开始. (1)当j=1时,next=0: (2)当存在前缀=后缀情况,next=相同字符数+1: ( ...

  5. A Tour of Go Exercise: HTTP Handlers

    Implement the following types and define ServeHTTP methods on them. Register them to handle specific ...

  6. python 使用__slots__

    正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Studen ...

  7. Java数组的内存管理

    Java数组的内存管理 Java语言是典型的静态语言,因此Java的数组是静态的,即当数组被初始化之后,该数组的长度是不可变的.Java程序中的数组必须经初始化才能使用.所谓初始化,就是当数组对象的元 ...

  8. 运用集合来做一个DVD管理器(全代码)

    package DVD;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Array ...

  9. C++学习笔记(三):数组

    数组声明时必须指定该数组的长度: ]; 这个时候已经分配了内存,但没有初始化,所以具体的值是不确定的: 初始化: ] = {, , }; ] = {};//指定第一个数字为1,后面的使用0填充: ] ...

  10. Stage3D学习笔记(二):使用GPU绘制一个三角形

    我们需要使用到Adobe自家提供的AGALMiniAssembler代码类,可以在网下进行下载: 关于AGAL的入门知识可以参考下面的文章: AGAL介绍系列文章(第一部分)AGAL介绍系列文章(第二 ...