MySQL OCP888题解025-MySQL的内存使用机制

文章详细阐述了MySQL如何分配内存,包括每个连接的线程内存、InnoDB缓冲池、MyISAM键缓冲区以及全局内存资源的分配情况。重点讨论了InnoDBbufferpool的作用和配置,线程的专用内存空间如栈、连接缓冲区和排序缓冲区,以及读缓冲区和随机读缓冲区的使用。
摘要由CSDN通过智能技术生成

1、原题

1.1、英文原题


Which two options describe how MySQL Server allocates memory?
A. Each connection may have its own per-thread memory allocations.
B. Thread memory is pre-allocated up to thread cache size for performance.
C. Each thread allocates memory from a global pool.
D. Global memory resource are allocated at server startup.

1.2、中文翻译

哪两个选项描述了MySQL Server如何分配内存?
A. 每个连接可以有自己的线程内存分配。
B. 线程内存预先分配到线程缓存大小以提高性能。
C. 每个线程从全局池分配内存。
D. 在服务器启动时分配全局内存资源。

1.3、答案

A、D

2、题目解析

2.1、题干解析

本题考察的是MySQL的内存使用机制。

2.2、选项解析

  1. 每个连接都会有自己的内存分配,主要用于栈内存、连接缓冲区和结果缓冲区,另外根据实际情况,可能每个连接还会用到随机读缓冲区和排序缓冲区。所以选项A正确。
  2. 线程内存预分配时,连接缓冲区和结果缓冲区都会被分配到net_buffer_size大小,再根据需要进行调节。所以选项B错误。
  3. 缓冲池主要用于缓冲表数据、索引数据和查询缓存,每个线程分配的内存不是从缓冲池中分配的,所以选项C错误。
  4. 服务器启动时会分配缓冲池等全局内存资源,所以选项D正确。

3、知识点

3.1、知识点1:MySQL的内存使用机制

MySQL分配缓冲区和缓存以提高数据库操作的性能。默认配置旨在允许MySQL服务器在具有大约512MB内存的虚拟机上启动。你可以通过增加某些缓存和缓冲区相关系统变量的值来提高MySQL的性能。你也可以修改默认配置以在内存有限的系统上运行MySQL。

MySQL使用的内存主要作如下用途:

  • InnoDB buffer pool(InnoDB缓冲池):InnoDB专用
  • MyISAM key buffer:MyISAM专用
  • MySQL Performance Schema(MySQL性能模式):性能模式是一项在低水平上监控MySQL服务器执行的功能。性能模式动态地分配内存,根据实际的服务器负载调整其内存使用,而不是在服务器启动期间分配所需的内存。一旦内存被分配,它就不会被释放,直到服务器被重新启动。
  • 每个线程除了共享基础缓存(InnoDB缓冲池或MyISAM key buffer外),还会拥有自己的专用内存区,主要包括stack(栈内存空间)、connection buffer(连接缓冲区)、result buffer(结果缓冲区)。另外,每个连接因为执行的不同可能还会包括随机读缓冲区和排序缓冲区。
  • read buffer(读缓冲区):每个对表进行顺序扫描的请求都会分配一个读取缓冲区。
  • random-read buffer(随机读缓冲区):对表的随机读写会用到随机读缓冲区,从而避免磁盘搜索。
  • sort buffer(排序缓冲区):大多数执行排序的请求会分配一个排序缓冲区。
  • table cache(表缓存):所有使用中的表的处理程序结构都保存在表缓存中。

FLUSH TABLES 语句或 mysqladmin flush-tables 命令会一次性关闭所有不使用的表,并在当前执行的线程结束时将所有使用中的表标记为关闭。这有效地释放了大部分正在使用的内存。

官方参考文档

3.1.1、InnoDB buffer pool(InnoDB缓冲池)

  • 缓冲池是什么:InnoDB缓冲池是一个内存区域,用于保存表、索引和其他辅助缓冲区的InnoDB缓存数据。为了提高缓冲区管理的效率,缓冲区被实现为一个变种LRU算法的页面链表,从而很少使用的数据会从缓冲区中淘汰。
  • 缓冲池的初始化:InnoDB在服务器启动时为整个缓冲池分配内存,使用malloc()操作。
  • 缓冲池的大小:innodb_buffer_pool_size系统变量定义了缓冲池的大小。缓冲池的大小对系统性能很重要,一个太小的缓冲池可能会导致过度的搅动,因为页面从缓冲池中被冲走,但在很短的时间内又被需要。缓冲池太大,可能会因为对内存的竞争而导致交换。通常推荐innodb_buffer_pool_size值是系统内存的50%到75%。innodb_buffer_pool_size可以在服务器运行时动态配置。
  • 多缓冲池:在有大量内存的系统中,可以通过将缓冲池划分为多个缓冲池实例来提高并发性。innodb_buffer_pool_instances系统变量定义了缓冲池实例的数量。

3.1.2、MyISAM key buffer

MyISAM key buffer是MyISAM引擎专享的缓冲区,是被所有线程共享的。key_buffer_size系统变量决定了其大小。

3.1.3、每个线程专用的内存空间

  • 服务器用来管理客户端连接的每个线程都需要一些线程专用的空间。下面的列表指出了这些空间以及哪些系统变量控制它们的大小。

    • A stack:栈内存空间,thread_stack系统变量控制大小。
    • A connection buffer:连接缓冲区,net_buffer_length系统变量控制带下。
    • A result buffer:结果缓冲区,net_buffer_length系统变量控制大小。
  • 连接缓冲区和结果缓冲区开始时的大小都等于net_buffer_length字节,但根据需要动态地扩大到max_allowed_packet字节。在每个SQL语句之后,结果缓冲区会收缩到net_buffer_length字节。

  • 每个连接线程使用内存来计算语句摘要。服务器为每个会话分配max_digest_length字节。

  • 当一个线程不再需要时,分配给它的内存会被释放并返回到系统中,除非该线程回到线程缓存中。在这种情况下,该内存仍然被分配。

3.1.4、read buffer(读缓冲区)

每个对表进行顺序扫描的请求都会分配一个读取缓冲区。read_buffer_size系统变量决定了缓冲区的大小。

3.1.5、random-read buffer(随机读缓冲区)

当以任意顺序读取行时(例如,按照排序),可以通过被分配的随机读缓冲区从而避免磁盘搜索。read_rnd_buffer_size系统变量决定了缓冲区的大小。

3.1.6、sort buffer(排序缓冲区)

大多数执行排序的请求会分配一个排序缓冲区和0到2个临时文件,这取决于结果集的大小。

3.1.7、 table cache(表缓存)

MySQL需要内存和描述符用于表缓存。所有使用中的表的处理程序结构都保存在表缓存中,并以 “先进先出”(FIFO)的方式管理。table_open_cache系统变量定义了初始表缓存大小;

4、总结

  1. MySQL内存主要用于如下用途
    1. InnoDB缓冲池;缓冲表数据、索引数据,InnoDB专用。
    2. MyISAM Key Buffer:MyISAM专用。
    3. 每个线程专用内存:主要用于栈内存、连接缓冲区、结果缓冲区,如果涉及排序可能还有排序缓冲区,如果涉及随机读还有随机读缓冲区
    4. read buffer(读缓冲区):对每个表的读取都会分配读缓冲区。
    5. table cache(表缓存):缓存每张表的表结构。
  2. 线程内存的分配并不会从InnoDB缓冲池中分配,所以可以简单认为所有线程分配的内存+InnoDB缓冲池内存等于MySQL使用的总内存大小。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值