MySQL 内存结构 缓冲池

发布于 2025-01-16 21:34:36 字数 3319 浏览 10 评论 0

应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(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 链表中呢?

  1. 当 InnoDB_old_blocks_time 的参数值设置为 0 时。当 old 部分的数据页被访问到时,该数据页会被提升到链表的头部,并被标记为 new 数据页。
  2. 当 InnoDB_old_blocks_time 的参数值大于 0 时(以 1000 毫秒或者 1 秒为例)。old 部分数据页插入缓冲池后,1 秒之后被访问,该数据页会被提升到链表的头部,并被标记为 new 数据页。在刚插入到一秒内,即便 old 部分的数据页被访问,该数据页也不会移动到 new 链表的头部。

使用 MySQL 命令 show variables like ‘innodb_old%’;可以查看 InnoDB 缓冲池结构的参数信息

  1. innodb_old_blocks_pct:控制 old page 子链表在 LRU 链表中的长度。
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

思慕

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文