详解分析MySQL8.0的内存消耗

 更新时间:2021年3月23日 15:00  点击:3414

  在MySQL8.0在启动的时候,会配置各种各样的buffer和cache来提高数据库的性能。如果我们在一台服务器上配置了MySQL8.0的服务,那么这台服务器的内存会同时被操作系统、MySQL8.0服务、以及其他应用程序所共享。

   生产环境中,经常会遇到内存的报警,在处理这些报警之前,你需要知道MySQL本身消耗内存最多的点在哪里,这样才能比较直观的判断出来你的MySQL服务占用的内存有多少,以及如何降低MySQL本身的内存消耗。

   在MySQL配置文件中,最常用的两个内存相关的参数是innodb_buffer_pool_size、innodb_log_buffer_size,我们来看这两个参数。

1、innodb_buffer_pool_size

这个参数定义了buffer pool的大小,大家可能都比较熟悉,buffer pool中的内容包含innodb 表、索引、以及其他的辅助buffer,buffer pool的大小对MySQL系统性能影响比较大,默认情况下,MySQL8.0配置的buffer pool大小是128MB,通常情况下,如果是单机单实例,没有其他业务,那么MySQL官方建议配置的大小为系统内存的50%到75%之间。当然,如果你的服务器上还部署了其他的应用程序,那么你需要酌情减小这个比例,从而腾出内存。

如果你的操作系统的内存很充裕,你可以设置多个innodb buffer pool实例,可以使用下面的参数来调整这个实例的个数:

mysql> show variables like '%innodb_buffer_pool_instances%';
+------------------------------+-------+
| Variable_name    | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1  |
+------------------------------+-------+
1 row in set (0.00 sec)

2、innodb_log_buffer_size

这个参数定义了innodb存储引擎向磁盘上写redo log之前,最多在内存中缓存数据的大小,默认是16MB。这个值增加之后,大的事务可以不用在事务提交之前将redo log落盘。如果你的update、delete和insert操作影响行数比较多,那么你需要考虑增大这个值。

重点来了:

在操作系统里面,MySQL占用的内存不仅仅是上述两个内存配置参数有关,通常情况下,我们计算MySQL占用的内存的时候,会使用下面4个值相加的方式:

1、innodb_buffer_pool_size

2、key_buffer_size  (这个参数通常是myisam表占用内存的关键参数)

3、max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size) (这三个是连接级别的buffer)

4、max_connections*2MB

所以当你使用top命令看到你的MySQL占用的内存远远超过innodb_buffer_pool_size的时候,你需要考虑的另外一个关键因素是连接数是否超标了,一旦连接数过高,那么上述3、4这两部分消耗的内存将会非常多。

当然,上面列举的,是MySQL最主要占用内存的几个因素,除此之外,其他的内存消耗的地方,可以查看官方文档:

https://dev.mysql.com/doc/refman/8.0/en/memory-use.html

上述文档中,还有介绍我们如何使用performance_schema来监控MySQL的内存使用,这里我提一下整个流程,详细的细节以及参数介绍请参看官方文档。

1、查看

performance_schema.setup_instruments

这张表,找到你关注的内存变量的名称(直接搜索,结果有490多条,分为好几个大类,一定记得过滤自己关注的参数)。举个例子,我们搜索memory/innodb相关参数,代表innodb存储引擎占用的内存,结果如下:

mysql> SELECT * FROM performance_schema.setup_instruments  WHERE NAME LIKE '%memory/innodb%';
+-------------------------------------------+---------+-------+-------------------+------------+---------------+
| NAME          | ENABLED | TIMED | PROPERTIES  | VOLATILITY | DOCUMENTATION |
+-------------------------------------------+---------+-------+-------------------+------------+---------------+
| memory/innodb/adaptive hash index   | YES  | NULL |     |   0 | NULL   |
| memory/innodb/log and page archiver  | YES  | NULL |     |   0 | NULL   |
| memory/innodb/buf_buf_pool    | YES  | NULL | global_statistics |   0 | NULL   |
| memory/innodb/buf_stat_per_index_t  | YES  | NULL |     |   0 | NULL   |
| memory/innodb/clone      | YES  | NULL |     |   0 | NULL   |
| memory/innodb/dict_stats_bg_recalc_pool_t | YES  | NULL |     |   0 | NULL   |
| memory/innodb/dict_stats_index_map_t  | YES  | NULL |     |   0 | NULL   |
| memory/innodb/dict_stats_n_diff_on_level | YES  | NULL |     |   0 | NULL   |
| memory/innodb/other      | YES  | NULL |     |   0 | NULL   |
| memory/innodb/partitioning    | YES  | NULL |     |   0 | NULL   |
| memory/innodb/row_log_buf     | YES  | NULL |     |   0 | NULL   |
| memory/innodb/row_merge_sort    | YES  | NULL |     |   0 | NULL   |
| memory/innodb/std       | YES  | NULL |     |   0 | NULL   |
| memory/innodb/trx_sys_t::rw_trx_ids  | YES  | NULL |     |   0 | NULL   |
| memory/innodb/undo::Tablespaces   | YES  | NULL |     |   0 | NULL   |
| memory/innodb/ut_lock_free_hash_t   | YES  | NULL |     |   0 | NULL   |
| memory/innodb/api0api      | YES  | NULL |     |   0 | NULL   |
| memory/innodb/api0misc     | YES  | NULL |     |   0 | NULL   |
| memory/innodb/btr0btr      | YES  | NULL |     |   0 | NULL   |

2、在配置文件中写上相关的参数,开启统计,以memory/innodb/row_log_buf为例,配置文件修改的如下:

performance-schema-instrument='memory/innodb/row_log_buf=COUNTED'

3、启动实例,并在performance_schema数据库的memory_summary_global_by_event_name表中查看内存统计结果。

SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE 'memory/innodb/row_log_buf'\G

当然,你还可以根据sys表中的结果,查看每个大类的聚合结果,如下:

mysql> SELECT SUBSTRING_INDEX(event_name,'/',2) AS
  code_area, FORMAT_BYTES(SUM(current_alloc))
  AS current_alloc
  FROM sys.x$memory_global_by_current_bytes
  GROUP BY SUBSTRING_INDEX(event_name,'/',2)
  ORDER BY SUM(current_alloc) DESC;
+---------------------------+---------------+
| code_area     | current_alloc |
+---------------------------+---------------+
| memory/innodb    | 843.24 MiB |
| memory/performance_schema | 81.29 MiB  |
| memory/mysys    | 8.20 MiB  |
| memory/sql    | 2.47 MiB  |
| memory/memory    | 174.01 KiB |
| memory/myisam    | 46.53 KiB  |
| memory/blackhole   | 512 bytes  |
| memory/federated   | 512 bytes  |
| memory/csv    | 512 bytes  |
| memory/vio    | 496 bytes  |
+---------------------------+---------------+

更详细的信息,请参见官方文档。

以上就是详解分析MySQL8.0的内存消耗的详细内容,更多关于MySQL8.0 内存消耗的资料请关注猪先飞其它相关文章!

[!--infotagslink--]

相关文章

  • 浅谈redis key值内存消耗以及性能影响

    这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
  • 详解分析MySQL8.0的内存消耗

    这篇文章主要介绍了详解分析MySQL8.0的内存消耗,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下...2021-03-23
  • 解决使用OpenCV中的imread()内存报错问题

    这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • 解决tensorflow训练时内存持续增加并占满的问题

    今天小编就为大家分享一篇解决tensorflow训练时内存持续增加并占满的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
  • 分享C#操作内存读写方法的主要实现代码

    这篇文章介绍了C#操作内存读写方法的主要实现代码,下面让我们来看看具体的实例实现,有需要的朋友可以参考一下...2020-06-25
  • C#托管内存与非托管内存之间的转换的实例讲解

    在本篇文章里小编给大家整理了关于C#托管内存与非托管内存之间的转换的实例以及相关知识点,需要的朋友们学习下。...2020-06-25
  • Java连接MySQL8.0 JDBC的详细步骤(IDEA版本)

    这篇文章主要介绍了Java连接MySQL8.0 JDBC的详细步骤(IDEA版本),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-06
  • c# 通过内存映射实现文件共享内存的示例代码

    这篇文章主要介绍了c# 通过内存映射实现文件共享内存的示例代码,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-04-24
  • Redis swap空间(虚拟内存)的使用详解

    这篇文章主要介绍了Redis swap空间的使用示例,帮助大家更好的理解和学习使用Redis数据库,感兴趣的朋友可以了解下...2021-03-25
  • Android内存溢出及内存泄漏原因进行

    这篇文章主要介绍了Android内存溢出及内存泄漏原因进行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-06
  • 完美解决TensorFlow和Keras大数据量内存溢出的问题

    这篇文章主要介绍了完美解决TensorFlow和Keras大数据量内存溢出的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-04
  • MySQL8.0升级的踩坑历险记

    听说mysql8的性能提升了很多,对于我这种喜欢把所有软件升级到最新版的人来说,二话不说直接升级,这篇文章主要给大家介绍了关于MySQL8.0升级踩坑的相关资料,需要的朋友可以参考下...2021-10-28
  • mysql 8.0.22 安装配置方法图文教程

    这篇文章主要介绍了mysql 8.0.22 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-10-27
  • Redis fork进程分配不到内存解决方案

    这篇文章主要介绍了Redis fork进程分配不到内存解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-01-15
  • java应用开发之JVM运行时内存分析

    这篇文章主要介绍了java应用开发之JVM运行时内存,文中附含图文示例内容分析非常简要,有需要的朋友可以借鉴参考下,希望能够有所帮助...2021-09-16
  • 对比C语言中memccpy()函数和memcpy()函数的用法

    这篇文章主要介绍了对比C语言中memccpy()函数和memcpy()函数的用法,二者都是用于复制内存内容,注意区别,需要的朋友可以参考下...2020-04-25
  • vivo x9总提示内存不足安装软件失败怎么办?

    vivo x9老是提示内存不足应该怎么处理?下面小编整理了解决办法,一起来看一看吧。 问:vivo x9总提示内存不足安装软件失败怎么办?答:内存不足一般有两种,一个是运行内存...2017-01-22
  • eMMC5.1和UFS2.0两种材质的手机内存哪个更好?有什么区别?

    2016年,安卓手机配置再次提升到了一个新的档次,骁龙820、4GB大内存,存储也飙到了128GB,而在这里,有一个很小的细节,那就是采用了UFS2.0闪存,而不是之前比较流行的eMMC5.1,那么eMMC5.1和UFS2.0两种材质的手机内存哪个更好?有什么区别?下面我们一起来了解下吧...2016-09-12
  • c++对象内存布局示例详解

    C++类的内存布局跟结构体有点像,实际上,类中成员变量的内存布局规则跟结构体是一样的,区别在于函数,虚函数的放置,下面这篇文章主要给大家介绍了关于c++对象内存布局的相关资料,需要的朋友可以参考下...2021-10-24
  • window10下mysql 8.0.20 安装配置方法图文教程

    这篇文章主要为大家详细介绍了window10下mysql 8.0.20 安装配置方法图文教程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-15