MySQL 内存结构 缓冲池
应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache) 里,避免每次都去访问数据库。操作系统,会有缓冲池(buffer pool) 机制,避免每次访问磁盘,以加速数据的访问。MySQL 作为一个存储系统,同样具有缓冲池(buffer pool) 机制,以避免每次查询数据都进行磁盘 IO。
- 缓冲池(InnoDB buffer pool)
- data page
- index page
- insert buffer
- lock info
- 自适应哈希索引
- 数据字典信息
- 重做日志缓冲(redo log buffer)
- 额外的缓冲池
1. 查看缓冲池信息
使用 MySQL 命令 show variables like ‘innodb%pool%’;
可以查看 InnoDB 缓存池的相关参数信息。
InnoDB_buffer_pool_size :用于设置 InnoDB 缓存池(InnoDB_buffer_pool) 的大小。
InnoDB 缓存池的大小对 InnoDB 整体性能影响较大,如果当前的 MySQL 服务器专门用于提供 MySQL 服务,应尽量增加 InnoDB_buffer_pool_size 的大小,把频繁访问的数据都放到内存中来,尽可能减少 InnoDB 对硬盘的访问,争取将 InnoDB 最大化成为一个内存型存储索引的访问,争取将 InnoDB 最大化成为一个内存存储引擎。
InnoDB_buffer_pool_instances: 默认值是 1,表示 InnoDB 缓存池被划分到一个区域。适当地增加该参数(例如将该参数值设置为 2),此时 InnoDB 被划分成为两个区域,可以提升 InnoDB 的并发性能。如果 InnoDB 缓存池被划分成多个区域,建议每个区域不小于 1GB 的空间。
InnoDB_additional_mem_pool_size :指定 InnoDB 用来存储数据字典和其他内部数据结构的缓存大小,默认值是 2MB。InnoDB 表的个数越多,该参数的值就应该设置得越大;当 InnoDB 用完缓存空间时,InnoDB 就会操作系统申请内存空间,并向错误日志写入一条警告信息。
2. 缓冲池内部数据结构
InnoDB 在内存中维护一个缓存池用于缓存数据和索引。缓存池可以被认为一条长 LRU 链表,该链表又分为 2 个子链表,一个子链表存放 old pages(里面存放的是长时间未被访问的数据页),另一个子链接存放 new pages(里面存放的是最近被访问的数据页面)。其余为 new pages 占用,如图下图所示。靠近 LRU 链表头部的数据页表示最近被访问,靠近 LRU 链表尾部的数据页表示长时间未被访问,而这两个部分交汇处成为 midpoint。
当用户需要访问数据时,InnoDB 首先会在 InnoDB 缓冲池查找数据,如果缓冲池中没有数据时,InnoDB 会将硬盘上的数据块插入到 InnoDB 缓存池中;如果 InnoDB 缓冲池已满,InnoDB 通过 LRU 算法清楚 InnoDB 缓存池中个别数据块。每当有新数据块需要加载到 InnoDB 缓冲池中时,该数据块应变为‘数据页’被插到 midpoint 的位置,并声明为 old 数据页。那么 old 数据页什么时候能移动到 new Page 链表中呢?
- 当 InnoDB_old_blocks_time 的参数值设置为 0 时。当 old 部分的数据页被访问到时,该数据页会被提升到链表的头部,并被标记为 new 数据页。
- 当 InnoDB_old_blocks_time 的参数值大于 0 时(以 1000 毫秒或者 1 秒为例)。old 部分数据页插入缓冲池后,1 秒之后被访问,该数据页会被提升到链表的头部,并被标记为 new 数据页。在刚插入到一秒内,即便 old 部分的数据页被访问,该数据页也不会移动到 new 链表的头部。
使用 MySQL 命令 show variables like ‘innodb_old%’;可以查看 InnoDB 缓冲池结构的参数信息
- innodb_old_blocks_pct:控制 old page 子链表在 LRU 链表中的长度。
- innodb_old_blocks_time:控制 old page 子链表的数据页移动到 new page 子链表中的时机。
3. 缓冲池数据预读
MySQL 服务启动一段时间后,InnoDB 会将经常访问的数据(包括业务数据,管理数据)置入 InnoDB 缓冲池中,即 InnoDB 缓冲池保存的是频繁访问的数据(简称热数据)。当 InnoDB 缓冲池的大小是几十 GB 甚至是几百 GB 时,由于某些原因(例如数据库定期维护)重启 MySQL 服务,如何将之前 InnoDB 缓冲池中的热数据重新加载到 InnoDB 缓冲池中?简单地说:如何对 InnoDB 缓冲池进行预热,以便于 MySQL 服务器快速地恢复到重启 MySQL 服务之前的性能状态?
从 5.6 版本开始,MySQL 支持关闭 MySQL 服务时将内存中的热数据保存到硬盘,MySQL 重启后首先将硬盘中的如数据加载到 InnoDB 缓冲池中,以便缩短 warmup 进程的时间,提高业务繁忙高并发时的效率。使用 MySQL 命令 show variables like ‘%innodb%pool%’;‘可以查看有关 InnoDB 缓冲池预热功能参数设置。
- innodb_buffer_dump_at_shutdown :默认为关闭 OFF。如果开启该参数,停止 MySQL 服务时,InnoDB 将 InnoDB 缓冲池中的热数据保存到本地硬盘。
- innodb_buffer_pool_load_at_startup: 默认为关闭 OFF。如果开启该参数,启动 MySQL 服务时,MySQL 将本地热数据加载到 InnoDB 缓冲池中。
- innodb_buffer_pool_load_now: 默认为关闭 OFF。如果开启该参数,停止 MySQL 服务时,以手动方式将 InnoDB 缓存池中的热数据保存到本地硬盘。
- innodb_buffer_pool_filename: 如果开启 InnoDB 预热功能,停止 MySQL 服务时,MySQL 将 InnoDB 缓冲池中的热数据保存到数据库根目录中,默认文件名为 ib_buffer_pool。
- innodb_buffer_pool_load_aborr: 默认为关闭 OFF。如果开启该参数,即便开启 InnoDB 预热功能,启动 MySQL 服务室,MySQL 也不会将本地硬盘的热数据加载到 InnoDB 缓冲池中。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: Hadoop 学习笔记和常见问题
下一篇: Web 容器有几种作用域?
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论