存储引擎InnoDB的内存架构 | 豆包MarsCode AI刷题

54 阅读4分钟

学习完LSMT存储引擎,让我想起了MySQL的存储引擎InnoDB,通过官方文档学习完之后,对InnoDB有了进一步了解。

1. 引言

存储引擎在数据库管理系统中扮演着至关重要的角色,它们负责数据的存储、检索和管理。不同存储引擎采用不同的数据结构和算法来存储和管理数据。

在早期的数据库系统一般都采用 B-Tree 家族作为索引(因为B-Tree数据结构出现得比较),例如 MySQL。2000 年后诞生的数据库大多采用 LSMT 索引,例如 HBase,RocksDB 等。

本文先从内存架构方面来介绍InnoDB这个存储引擎。

2. 架构

下图是MySQL 8.4 的InnoDB架构,分为两个板块:内存架构磁盘架构

2.1. 内存架构
2.1.1. 缓冲池(Buffer Pool)

缓冲池是主内存中的一个区域,用于 InnoDB 缓存访问的表和索引数据。缓冲池允许直接从内存访问常用数据,从而加快处理速度。

  • 为了提高大容量读取操作的效率,缓冲池被划分为可容纳多行的页面。
  • 为了提高缓存管理的效率,缓冲池被实现为页面的链接列表;
  • 使用最近最少使用 (LRU) 算法的变体将很少使用的数据从缓存中淘汰。

也就是说当读取数据时会进行以下的步骤:

(1)检查缓冲池:当InnoDB需要读取某个数据页或索引页时,首先会在缓冲池中查找是否存在该页。

(2)命中缓存:如果该页已经在缓冲池中(缓存命中),InnoDB直接从缓冲池中读取数据,避免了磁盘I/O操作。

(3)未命中缓存:如果该页不在缓冲池中(缓存未命中),InnoDB会从磁盘读取该页到缓冲池中。

(4)替换策略:如果缓冲池已满,InnoDB会根据替换策略(如LRU算法)选择一个不常用的页进行替换,将新读取的页加载到缓冲池中。

2.1.2. 变更缓存(Change Buffer)

变更缓冲区是一种特殊的数据结构, 当这些页面不在缓冲池中时,它会缓存对二级索引页面的更改。 缓冲的更改可能是由insertupdatedelete 操作 (DML) 引起的,稍后当其他读取操作将页面加载到缓冲池中时,会合并这些更改。

2.1.3. 自适应hash索引(Adaptive Index)

InnoDB存储引擎会监控对表上各索引页的查询,它会根据这些查询自动创建哈希索引。这个过程是动态的,不需要手动设计或定义哈希索引。构造过程如下:

(1)查询记录:InnoDB 会持续监控和记录数据库的查询活动。当系统检测到某些键(通常是二级索引列)被频繁访问时,这些键就会成为自适应哈希索引的候选。

(2)哈希值计算:当 InnoDB 识别到特定的查询模式时,它会创建一个哈希表。这个哈希表的每个条目都是将索引键经过哈希函数处理后得到的哈希值。哈希值会映射到相应的数据行,这样可以快速定位行

(3)实时更新:在生成哈希表时,InnoDB 将所需的数据从原始索引页提取出来,并根据哈希值进行存储。此过程是在内存中进行的,以减少对磁盘的依赖,提高检索速度。

(4)自动调整:自适应哈希索引不仅在创建时是动态的,而且在新的查询模式出现或原有模式不再频繁使用时,它也会动态调整。例如,如果某个查询模式逐渐不再使用,InnoDB 可能会决定删除或缩减对应的哈希条目,以释放内存。

2.1.4. 日志缓冲区 (Log Buffer)

日志缓冲区是用于保存要写入磁盘日志文件的数据的内存区域。日志缓冲区大小由变量定义 innodb_log_buffer_size。默认大小为 64MB。日志缓冲区的内容会定期刷新到磁盘。大型日志缓冲区使大型事务能够运行,而无需在事务提交之前将重做日志数据写入磁盘。因此,如果您有更新、插入或删除多行的事务,则增加日志缓冲区的大小可以节省磁盘 I/O。

参考链接:

hhttps://dev.mysql.com/doc/refman/8.4/en/innodb-in-memory-structures.html

blog.csdn.net/w1014074794…