MySQL如何使用内存

2020-03-31  本文已影响0人  月饮沙

本文问题

  1. MySQL内存使用可以分为哪几大类?
  2. 在MySQL中,哪些内存是自动释放的,哪些内存是可以手动释放的,哪些内存是只能重启释放的?
  3. 对于InnoDB和MyISAM存储引擎,MySQL分配内存有什么区别?

内存使用情况

存储引擎

InnoDB

InnoDB缓冲池,大小通过innodb_buffer_pool_size定义,里面包含了InnoDB的表的数据、索引和一些额外信息。
数据库启动时通过malloc()函数分配整个缓冲池大小的内存。可以在数据库运行时,通过修改innodb_buffer_pool_size大小来手动释放部分内存。

MyISAM

MyISAM索引缓存,这部分内存由所有线程共享。大小通过key_buffer_size定义。
对于MyISAM表的打开,索引文件只打开一次,每个对表的并行访问都会打开一次数据文件。对于每个并发线程,缓存表结构,每个列的列结构,并且会缓存一个大小为3*N的缓冲区(N是除了BLOB以外其他列的最大行大小)。BLOB列需要BLOB数据再加上额外的5-8 bytes。MyISAM存储引擎维持一个额外的行缓冲区用于内部使用
myisam_use_mmap 是否使用内存映射来读写MyISAM表。

临时表

内部临时表

内部临时表的大小由tmp_table_sizemax_heap_table_size中较小值决定其最大大小。超过两者中的最小值后会由内存表转换为磁盘表。

用户创建的临时表

通过CREATE TABLE语句创建的内存表,max_heap_table_size定义了表的最大大小,并且这类表不会转换为临时表

Performance_schema

Performance_schema在需要时动态增加内存。这部分内存一旦分配,只能通过重启数据库进行释放

线程

所有线程共享相同的基本内存
每个线程还需要一些特定与线程的内存,当线程结束时,分配给线程的内存会释放回操作系统。如果线程结束后进入到线程缓冲池,分配给线程的内存不会释放。

请求

顺序读请求会分配一个读缓冲区 read_buffer_size
随机读请求也会分配一个随机读缓冲区 read_rnd_buffer_size
联接join语句一次执行,大多数join可以在不使用临时表的情况下完成,大部分临时表时内存表。
大部分排序请求根据结果集的大小,分配一个排序缓冲区和0到2个临时文件。
基本上所有的解析和计算都在线程本身的可重用的内存池中完成。对于小的项目,不需要内存开销,这可以避免大量小内存分配和释放。只有意外出现大字符串的时候才需要分配内存。
对于每个BLOB列,将动态扩展缓冲区以读取BLOB值。在扫描表的时候,缓冲区将增大到BLOB列的最大值。

表缓存

MySQL需要为表缓存提供内存和文件描述符。所有使用中的表结构都存储在表缓存中,并按照先进先出原则进行管理。table_open_cache定义了初始表缓存的大小
MySQL也需要为表定义缓存提供内存。table_definition_cache定义了可以在表定义缓存中缓存的表定义文件(.frm文件)数量。
FLUSH TABLES语句或者mysqladmi flush-tables命令立即关闭所有未使用的表,并在线程执行结束时将所有正在使用中的表标记为关闭。这样可以释放大多数使用中的内存。FLUSH TABLES在关闭所有表之前不会返回

权限

数据库在内存中缓存 GRANT,CREATE USER,CREATE SERVER以及INSTALL PLUGIN语句的结果。
这些内存不会通过REVOKE,DROP USER,DROP SERVERUNINSTALL PLUGIN语句释放。
所以执行许多这类语句会导致缓存使用增加,这部分内存可以使用FLUSH PRIVILEGES语句释放。

问题答案

  1. MySQL内存使用可以分为哪几大类?
  1. 在MySQL中,哪些内存是自动释放的,哪些内存是可以手动释放的,哪些内存是只能重启释放的?
  1. 对于InnoDB和MyISAM存储引擎,MySQL分配内存有什么区别?
    InnoDB使用InnoDB缓冲池,其中包括数据和索引,由innodb_buffer_pool_size定义其大小
    MyISAM使用MyISAM索引缓存,其中只包括索引,由key_buffer_size定义其大小
上一篇 下一篇

猜你喜欢

热点阅读