【Mysql】升级到MySQL 5.7的又一个理由——分区问题


640?wx_fmt=jpeg&tp=webp&wxfrom=5




  1. 前言

  1. 经常有小伙伴问Inside君,MySQL的分区(partition)怎么样?能用不?是不是有很多bug?不知MySQL的分区为何会给普罗大众这样的印象。但Inside君的印象中,分区影响比较大的bug就下面的一例(严格意义也很难说是bug),也是小伙伴们咨询Inside君分区遇到最多的问题。不过,好在这个bug已在5.7版本中得到了修复(准确来说是5.7支持了Native Paritition)。看来又多了一个升级到5.7的理由。总结来说,生产环境有必要每天弄个分区嘛?


  1. 正文
  1. 一个月之前,Scott和同事们发现公司有一个MySQL MHA集群的master(假设master机器名为hostA)每隔一周左右就会挂一次(指MySQL挂掉),在几周内,MHA来回切了好几次。
  2.  
  3.  按照国际惯例,Scott按照如下顺序去查问题到底出在哪里:
  4.  1. 先翻MySQL error log,没有发现异常
  5. 2. 再翻Linux系统日志文件,果然,翻到了下面的内容:

  6. Nov 26 13:05:38 hostA kernel: mysql invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0
  7.  ......
  8.  Nov 26 13:05:38 hostA kernel: Out of memory: Kill process 32271 (mysqld) score 976 or sacrifice child
  9.  Nov 26 13:05:38 hostA kernel: Killed process 32271, UID 496, (mysqld) total-vm:83064212kB, anon-rss:64204132kB, file-rss:4544kB
  10.   

  11. 该机器的物理内存大小为62G,从上面的日志看,MySQL确实已经把它用满了。该机器上MySQL的innodb_buffer_pool=31G,Scott认为这已经相当保守了,而且各种buffer_size我们都使用的是默认值,MySQL OOM时的用户连接数是100+
  12.  
  13.  这些目测都没有什么问题,但是居然还是发生了OOM,实在是不可思议。当时觉得就是内存不够用了呗,没有查出具体原因,后来62G的内存加到了125G(innodb_buffer_pool_size增大到64G,这值确实很保守),还是发生了OOM。
  14.  
  15.  其实一开始Scott就发现,这台机器上有一个更早的问题,就是因为系统最大文件打开数不够导致这台机器的xtrabackup备份总是不成功,具体是什么原因请等Scott去整理xtrabackup备份的更详细的过程。然后我去检查了该机器上面的*.ibd文件和*.frm文件数量,吓我一跳(话说Inside君也是吓尿了):

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

  20.  也就是说,该机器上面竟然有17万个ibd文件,但是只有2534张表,很明显是分区表中的分区数量非常多。
  21.  
  22.  [userA@hostA mysql]$ sudo find . -name '*par*' | wc -l
  23.  1882
  24.  
  25.  Scott仔细比较了这台机器和其他没有问题的机器的不同,发现这台机器上面分区数量太多是唯一的一个不同,这让Scott没有办法不怀疑是分区导致的问题。
  26.  
  27.  Scott仍然按照国际惯例,第一时间去查MySQL 5.6的官方文档,无果。。。(官方文档虽然不是万能的,但是仍然是出现问题的第一参考资料)。去MySQL的bugs页面搜索关于partition的bug,无果。。。去google了下,发现有的比较杂的网站上面写道MySQL分区数量太多引发内存耗尽的问题,但是文章讲的内容感觉不是很正确。
  28.  
  29.  最后在姜老师的指点下,看了这篇文章:
  30.  
  31.  http://mysqlserverteam.com/innodb-native-partitioning-early-access/
  32.  
  33.  上面是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表的内存开销基本是一样的。
  34.   
  35. 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:
  36.   
  37. 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)!

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



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29096438/viewspace-1979021/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29096438/viewspace-1979021/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值