导读

作者:Sveta Smirnova

翻译:郑志江

校对:徐晨亮

原文 :MySQL Memory Management, Memory Allocators and Operating System

本文涉及链接在文末展示

当用户使用任何软件(包括MySQL)碰到内存问题时,我们第一反应就是内存泄漏。正如这篇文章所示,其实并不总是这样。

这篇文章阐述一个关于内存的bug。

所有percona所支持的客户都有获得bug修复的资格,但他们也有不同的选择。比如,vip客户在软件补丁正式发布之前就可以获得hotfiix版本,高级客户甚至不需要使用percona的软件,我们也可以为他们把补丁推到上游。但对于与percona产品来说,所有支持等级都有权得到bug修复。

即便如此,这并不意味着我们会修复所有的意外情况,即使我们接受这种情况为一个有效bug。做出这样的决定的原因之一可能是这个意外情况虽然很明确是错误的,但对于percona产品本身来说确实一个产品需求

作为学习案例的一个bug

最近一个很好的案例是 PS-5312——这个bug可在上游复现并被记录在bugs.mysql.com/95065。

这个报告阐述了一种情况,当访问InnoDB的全文索引的时候会导致内存使用量增长。这种情况出现在一些全文索引的查询,内存会持续增长直到达到最大值,并且很长时间不会释放。

来自Percona工程团队的Yura Sorokin研究表明,这种情况并不属于内存泄漏范畴。

当InnoDB解析一个全文查询时,它会在fts_query_phrase_search函数中创建一个内存堆,这个堆可能增长到80M。另外,这个过程还会使用到大量非连续块(mem_block_t)进而产生的内存碎片。

在函数出口,这些内存堆会被释放。InnoDB会为其分配的每一个块做这个操作。在函数执行结束时,调用一个内存分配器库中的free()操作,比如malloc或者jemalloc。从MySQL本身来看,这都是没问题的,不存在内存泄漏。

然而,free()函数被调用时确实应该释放内存,但不需要将其返回给操作系统。如果内存分配器发现这些内存块马上还需要被用到,则会将他们保留住继续用于mysqld进程。这就解释了为什么mysqld在完成工作及释放内存都结束后还会占用大量内存。

这个在实际生产中并不是一个大问题,按道理不应该造成任何事故。但是如果你需要更快地将内存返回给操作系统,你可以尝试非传统的内存分配器,类似jemallolc。它被证明可以解决PS-5312的问题。

另一个改善内存管理的因素是cpu内核数量:在测试中,cpu核数越多,内存返回给操作系统的速度会越快。这可能是你拥有多个CPU,而其中一个可专门用作内存分配器释放内存给操作系统。

正如我们的工程师Yura Sorokin所发现的一样,下面两点阐述了InnoDB全文索引的早期实现引入了这个缺陷:

5.6版本MySQL最早对InnoDB WL全文索引功能引入的介绍:#5538: InnoDB全文搜索支持 – https://dev.mysql.com/worklog...

实现WL #5538 InnoDB全文搜索支持与合并 - https://github.com/mysql/mysq... - 也存在同样的问题问题

修复方法

我们有两种方法来修复这个问题:

1.修改InnoDB全文索引的实现

2.使用自定义内存库,例如jemalloc

这两种方法都有各自的优缺点。

方法1 :意味着我们引入了与软件上游不兼容性的风险,这可能会导致新版本中出现未知的错误。也意味着彻底重写InnoDB全文索引部分代码,这在用户们使用的GA版本中是有风险的。

方法2 则意味着我们可能会命中一些jemalloc库中专门为性能设计但不是最安全的内存分配的bug。

因此我们不得不在这两个并不完美的方法中选择一个。

鉴于方法一可能导致percona服务与上游的不兼容,我们更倾向于用方法二来解决问题,并期待着上游修复这个bug。

结论

如果发现mysqld进程占用内存很高,并不代表一定是内存泄漏。我们可以在Performance Schema中使用内存检测来了解进程是如何使用已分配的内存。也可以尝试替换内存库来更好地处理内存分配与释放。关于LD_RELOAD如何配置,请查阅MySQL用户手册对应页面 mysqld-safe和using-system。

mysql 自动管理内存_MySQL内存管理,内存分配器和操作系统相关推荐

  1. mysql 用户管理表_mysql用户管理

    msyql用户定义: 使用某个用户 从哪个(些)地址访问我的数据库 主机范围 单独IP:'10.0.0.200' 一个网段:'10.0.0.%' --->10.0.0.1-->10.0.0 ...

  2. mysql 自动补零_mysql 补零

    云数据库 MySQL 云数据库(RDS for MySQL)是稳定可靠.可弹性伸缩的云数据库服务.通过云数据库能够让您几分钟内完成数据库部署.云端完全托管,让您专注于应用程序开发,无需为数据库运维烦恼 ...

  3. mysql自动增长恢复_mysql自动增长的有关问题,怎么恢复从1开始

    mysql自动增长的问题,如何恢复从1开始 在一个表中我设置到autoid为自动增长列 例如有如下数据 1 张三 男 20 2 王五 男 22 3 李四 男 25 4 陈大 男 19 现在我把 aut ...

  4. jdbc mysql 自动重连_Mysql中JDBC如何完成自动重连机制的案例

    软件安装:装机软件必备包 SQL是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言.在使用它时,只需要发出& ...

  5. mysql 自动执行语句_MYSQL 定时自动执行任务

    MYSQL5.1开始支持EVENT功能,类似Oracle和MSSQL的定时任务job功能.有了这个功能之后我们就可以让MySQL自动的执行存储过程来实现数据汇总等功能了,不用像以前哪样手动操作完成了. ...

  6. mysql存储业务日志_MySQL 日志管理

    一.MySQL 日志 日志是mysql数据库的重要组成部分.日志文件中记录着mysql数据库运行期间发生的变化:也就是说用来记录mysql数据库的客户端连接状况.SQL语句的执行情况和错误信息等.当数 ...

  7. mysql管理节点_MySql节点管理安装步骤需要在SerA和SerB上各做一次

    对大家推荐很好使用的MySql节点系统,像让大家对MySql节点系统有所了解,然后对MySql节点系统全面讲解介绍,希望对大家有用在向大家详细介绍MySql节点之前,首先让大家了解下MySql节点,然 ...

  8. mysql分区表去重复_MySQL分区表管理

    RANGE,LIST分区管理 1:为未分区表创建分区 ALTER TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2; 2:删除某个分区的数据 ALTER TAB ...

  9. mysql是否truncate分区_MySQL分区管理

    以下是我看MySQL官方文档的时候整理的笔记,仅作参考保留. RANGE,LIST分区管理 1:为未分区表创建分区 ALTER TABLE trb3 PARTITION BY KEY(id) PART ...

  10. mysql的账户之间_MySQL用户管理

    MySQL服务器通过权限表来空值用户对数据库的访问,权限表存放在mysql数据库中,由mysql_install_db 脚本初始化,存储账户权限信息表主要有:user,db,host,tables_p ...

最新文章

  1. python语言程序设计书-清华大学出版社-图书详情-《Python语言程序设计》
  2. 微信小程序界面跳转(1)
  3. cogs 1456. [UVa 10881,Piotr's Ants]蚂蚁
  4. Java super关键字
  5. 常见Java面试题之和的区别?
  6. Ubuntu19.04安装mysql8.0版本(亲测OK)
  7. 二叉树的创建_大多数人都不会手写创建并遍历二叉树,一航这里帮你终结了
  8. HTML a链接下载文件之图片,文件,乱码等问题
  9. workman 心跳
  10. 电子口岸客户端控件首次安装
  11. 实探恒大FF南沙生产基地;百度外卖退出历史舞台;斗鱼永久关闭陈一发直播账号 | 雷锋早报...
  12. excel下拉列表多选框_移动Excel列表框项目
  13. 如何实现网易公开课的倍速播放?
  14. 关于JS按钮倒计时禁用的小Demo
  15. 手把手教你构建 C 语言编译器(1)- 设计
  16. C#根据驱动名称获得USB串口的端口实例
  17. 获取当前时间和一年后时间(中国标准时间)时间处理
  18. 现货黄金走势图怎么看?
  19. 【C语言练习】1.1弹跳小球
  20. 一套自动化无纸办公系统(OA+审批流)源码:带数据字典

热门文章

  1. UILabel显示带颜色边的文字
  2. logstash写入到kafka和从kafka读取日志
  3. postfix邮箱服务
  4. RPC-原理及RPC实例分析
  5. Android组件框架:Android组件管理者ActivityManager
  6. 【WP8】ResourceDictionary
  7. 如何修改 远程桌面的 默认端口号 3389
  8. php正则表达式函数 preg_replace用法
  9. Ruby环境的安装(In Ubuntu 7.10)
  10. 一文了解Python常见的序列化操作