背景

MySQL 版本: MySQL 5.7.20
硬件配置: 8C + 32GB + 1000GB

MySQL实际内存分配

  MySQL 的内存是一个重要的性能参数,常常出现由于异常的SQL请求以及待优化的数据库导致内存利用率升高的情况,严重时还会出现由于OOM导致数据库宕机,在没有做HA的情况下导致整个业务线的瘫痪。

MySQL的内存大体可以分为共享内存session私有内存两部分。

共享内存

执行如下命令,即可查询示例的共享内存参数分配情况:

show variables where variable_name in (
'innodb_buffer_pool_size',
'innodb_log_buffer_size',
'innodb_additional_mem_pool_size',
'key_buffer_size','query_cache_size'
);

输出示例:

+---------------------------------+-----------------+
| Variable_name                   | Value           |
+---------------------------------+-----------------+
| innodb_additional_mem_pool_size | 8388608         |
| innodb_buffer_pool_size         | 25769803776     |
| innodb_log_buffer_size          | 8388608         |
| key_buffer_size                 | 16777216        |
| query_cache_size                | 3145728         |
+---------------------------------+-----------------+
共返回 5 行记录,花费 342.74 ms.

参数说明
◎ innodb_buffer_pool_size
  该部分缓存是Innodb引擎最重要的缓存区域,是通过内存来弥补物理数据文件的重要手段,数据库实例上会采用实例规格配置的75%作为该部分大小。其中主要包括数据页、索引页、undo页、insert buffer、自适应哈希索引、锁信息以及数据字典等信息。在进行SQL读和写的操作时,首先并不是对物理数据文件操作,而是先对buffer_pool进行操作,然后再通过checkpoint等机制写回数据文件。该空间的优点是可以提升数据库性能、加快SQL运行速度,缺点是故障恢复速度较慢。
◎ innodb_log_buffer_size
  该部分主要存放redo log的信息,在RDS上会设置1M的大小。InnoDB会首先将redo log写在这里,然后按照一定频率将其刷新回重做日志文件中。该空间不需要太大,因为一般情况下该部分缓存会以较快刷新频率刷新至redo log(Master Thread会每秒刷新、事务提交时会刷新、其空间少于1/2时同样会刷新)。
◎ innodb_additional_mem_pool_size
  该部分主要存放InnoDB内的一些数据结构,在RDS中统一设置为2M。通常是在buffer_pool中申请内存的时候还需要在额外内存中申请空间存储该对象的结构信息。该大小主要与表数量有关,表数量越大需要的空间越大。
◎ key_buffer
  该部分是MyISAM表的重要缓存区域,所有实例统一为16M。该部分主要存放MyISAM表的键。MyISAM表不同于InnoDB表,其缓存的索引缓存是放在key_buffer中的,而数据缓存则存储于操作系统的内存中。RDS的系统是MyISAM引擎的,因此在RDS中是给予该部分一定量的空间的。
◎ query_cache
  该部分是对查询结果做缓存以减少解析SQL和执行SQL的花销,在RDS上关闭了该部分的缓存。主要适合于读多写少的应用场景,因为他是按照SQL语句的hash值进行缓存的,当表数据发生变化后即失效。

Session私有内存

  共享内存中介绍的内存空间是实例创建时即分配的内存空间,并且是所有连接共享的。而出现OOM异常的实例都是由于下面各个连接私有的内存造成的。
执行如下命令,查询示例的session私有内存分配情况:

show variables where variable_name in (
'read_buffer_size',
'read_rnd_buffer_size',
'sort_buffer_size',
'join_buffer_size',
'binlog_cache_size',
'tmp_table_size'
);

输出示例:

+-------------------------+-----------------+
| Variable_name           | Value           |
+-------------------------+-----------------+
| binlog_cache_size       | 262144          |
| join_buffer_size        | 262144          |
| read_buffer_size        | 262144          |
| read_rnd_buffer_size    | 262144          |
| sort_buffer_size        | 262144          |
| tmp_table_size          | 262144          |
+-------------------------+-----------------+
共返回 6 行记录,花费 356.54 ms.

参数说明
◎ read_buffer_size & read_rnd_buffer_size
  分别存放了对顺序和随机扫描(例如按照排序的顺序访问)的缓存,RDS给每个session设置256K的大小。当thread进行顺序或随机扫描数据是会首先扫描该buffer空间避免更多的物理读。
◎ sort_buffer_size
  需要执行order by和group by的SQL都会分配sort buffer,用于存储排序的中间结果,在RDS上设置256K。在排序过程中,若存储量大于sort_buffer_size,则会在磁盘生成临时表以完成操作。在Linux系统中,当分配空间大于2M是会使用mmap()而不是malloc()来进行内存分配,导致效率降低。
◎ join_buffer_size
  MySQL仅支持nest loop的join算法,RDS设置256K的大小。处理逻辑是驱动表的一行和非驱动表联合查找,这时就可以 将非驱动表放入join_buffer,不需要访问拥有并发保护机制的buffer_pool。
◎ binlog_cache_size
  该区域用来缓存该thread的binlog日志,RDS设置256K的大小。在一个事务还没有commit之前会将其日志存储于binlog_cache中,等到事务commit后会将binlog刷回磁盘上的binlog文件以持久化。
◎ tmp_table_size
  不同于上面各个session层次的buffer,这个参数可以在控制台上修改。该参数是指用户内存临时表的大小,如果该thread创建的临时表超过它设置的大小会把临时表转换为磁盘上的一张MyISAM临时表。如果用户在执行事务时遇到类似如下这样的错误,可以考虑增大tmp_table的值.

[Err] 1114 - The table '/home/mysql/data3081/tmp/#sql_6197_2' is full

MySQL 实际内存分配相关推荐

  1. mysql数据库内存分配_MySQL OOM 系列一 Linux内存分配

    RDS(网易云关系数据库服务)上线已经有一段时间,陆续不断有产品迁入到了RDS中,在线上运维的过程中,也遇到了一些曾经没有考虑到,或者考虑的不全的东西.后续有时间可以分享给大家. 今天想提到的是线上一 ...

  2. MySQL • 源码分析 • 内存分配机制

    摘要: 前言 内存资源由操作系统管理,分配与回收操作可能会执行系统调用(以 malloc 算法为例,较大的内存空间分配接口是 mmap, 而较小的空间 free 之后并不归还给操作系统 ),频繁的系统 ...

  3. mysql内存态_MySQL · 社区动态 · MySQL内存分配支持NUMA

    NUMA 问题曾经一直是困扰DBA的一个大问题,早在 2010 年, 就有人给MySQL报了Bug#57241, 指出了MySQL在x86系统下存在严重的 "swap insanity&qu ...

  4. 利用TCMalloc替换Nginx和Redis默认glibc库的malloc内存分配

    TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员.与标准的glibc库的Malloc相比,TCMalloc库在内存分 ...

  5. mysql进程内存不足_故障排除指南:MySQL的运行内存不足怎么办?

    原标题:故障排除指南:MySQL的运行内存不足怎么办? [ ] [IT168 评论]故障排除对于所有人来说都不会是一件有趣的事情,尤其是在没有崩溃报告的情况下.如果MySQL因内存不足而崩溃时应该怎么 ...

  6. (转)MySQL 服务器内存使用

    原文作者: Peter Zaitsev 原文来源: http://www.mysqlperformanceblog.com/2006/05/17/mysql-server-memory-usage 译 ...

  7. mysql cpu 内存占用_MySQL占用内存与CPU过高测试与解决办法

    为了装mysql环境测试,装上后发现启动后MySQL占用内存了很大,达8百多兆.网上搜索了一下,得到高人指点my.ini.再也没见再详细的了..只好打开my.ini逐行的啃,虽然英文差了点,不过多少M ...

  8. linux内核函数kmalloc,Linux_Linux平台上几个常见内核内存分配函数,* kmallocPrototype:#incl - phpStudy...

    Linux平台上几个常见内核内存分配函数 * kmalloc Prototype: #include void *kmalloc(size_t size, int flags); Kmalloc分配一 ...

  9. linux c 内存分配内存,Linuxc - 操作系统内存分配

    静态变量是存储在数据段的,在函数中可以共用. 全局变量也是存储在数据段的,在全局中可以共用. 指针变量本质上是地址,数组变量本质上也是地址. 数组是可靠的,不可变的地址.指针变量是不可靠的,可变的.数 ...

最新文章

  1. 第18章:MYSQL分区
  2. 转载 - Struts2基于XML配置方式实现对action的所有方法进行输入校验
  3. 【收藏】Maven 生成打包可执行jar包
  4. 初识空中计算(Over-the-Air Computation)
  5. canvas 从入门到入坟
  6. Android BroadcastReceiver(一)
  7. PyTricks 翻译:Python 字典的 get() 方法和它的默认参数
  8. 小程序源码:全新实用工具证件照制作微信小程序源码下载支持多种证件生成与制作
  9. 程序员如何在百忙中更有效地利用时间,如何不走岔路,不白忙(忙得要有效率,要有收获)
  10. Lesson 17.11 案例一:SVHN街道实景门牌识别
  11. 【寻找最佳小程序】01期:影视评分小工具“豆瓣评分”——产品设计要点及专家评析
  12. Golang验证身份证号码是否有效
  13. 有效年利率和年化百分比利率
  14. OTSU(最大类间方差法、大津算法)
  15. Eclipse无法启动
  16. 一座适合躺尸的低房价、慢节奏小城
  17. Arduino点亮LED灯带
  18. 互联网家装是伪命题?
  19. 百万CT网上卖,东软医疗这样推动行业阳光采购
  20. 墨者学院-编辑器漏洞分析溯源(第1题)

热门文章

  1. 数值逼近课程设计(1)——runge现象
  2. Xshell5以root用户登录Ubuntu系统
  3. Virbox品牌全新升级,软件加密行业引领者
  4. 把http升级到https——生命不息,折腾不止
  5. JAVA虚拟机的安装以及JAVA的环境配置
  6. 一、首页第一个首页栏制作【仿淘票票系统前后端完全制作(除支付外)】
  7. hexo设置网站的图标Favicon
  8. KDD‘20 | 如何建模互联网水军的对抗行为?
  9. Synaptic Systems NeuN抗体的应用和参考文献
  10. java会使电脑越来越慢吗_电脑越来越慢很卡怎么办