1367 字
7 分钟
MySQL11-InnoDB引擎01-架构
2023-06-06
2023-11-25

详细的描述了MySQL中的InnoDB引擎的架构。

逻辑存储结构#

InnoDB 表空间、段、区、页及页内记录的逻辑层级

原理示意:表空间组织存储页,索引使用段管理叶节点与非叶节点的空间,区由连续页构成,记录再组织在页内。默认页大小为十六千字节时,一个区包含六十四页;该关系不能无条件套到所有页大小配置,段也可以先分配零散页,长字段还可能引用溢出页。

架构#

总架构#

InnoDB 缓冲池、日志缓冲与磁盘表空间、双写和重做日志的关系

原理示意:缓冲池缓存数据页和索引页,日志缓冲区暂存重做记录。脏页经过相应保护路径写回表空间,而重做日志独立持久化,用于崩溃恢复。两条路径并不意味着提交时全部脏页已经落盘;更改缓冲、自适应哈希及不同表空间也不能混为同一种缓存文件。

内存结构#

缓冲池#

Buffer pool 的页命中、未命中装入与脏页刷新路径

原理示意:读写请求访问的是缓冲池中的页,命中时直接使用,未命中时才需要从相应表空间装入。修改后的页成为脏页,之后由刷新机制写回数据文件,相关重做记录必须先满足持久化要求。缓冲池不是查询结果缓存,也不能仅凭这张关系图推断命中率、磁盘读取量或查询耗时。

更改缓冲区#

更改缓冲区针对尚未在缓冲池中的、符合条件的非唯一二级索引页,暂存其索引项变更,等到页面被读入或后台合并时再应用。它不是缓存所有表行修改的通用队列,也不能替代重做日志。其内存部分占用缓冲池,持久化部分位于系统表空间;是否启用以及哪些操作可缓冲,取决于配置与索引条件。

自适应哈希#

自适应哈希索引由 InnoDB 观察索引访问模式后,按需为经常访问的索引页建立内存中的辅助查找结构。它可能只涉及部分索引键前缀,不是把整棵索引永久转换成哈希表,也不是用户创建的一种独立哈希索引。原有树形索引仍然存在;是否受益、是否启用,应结合实际工作负载判断。

日志缓冲区#

日志缓冲写入重做日志与脏页双写刷新的两条路径

原理示意:日志缓冲区保存待写入磁盘的重做记录,而不是待刷新的完整数据页。日志写入与刷盘时机受提交及刷新策略控制,不能把日志仍在内存理解为已经具备断电后的持久性。下方的双写页路径是另一类保护:页落盘前,相关重做记录须先持久化。

磁盘结构#

系统表空间与单个表文件空间#

系统表空间与独立表空间的职责不同。系统表空间保存更改缓冲等共享结构,也可按布局容纳表和索引;独立表空间则把单表的数据与索引组织在对应文件中。innodb_file_per_table 控制新建表的默认布局,但不代表所有既有表都自动搬入独立文件;数据字典与双写区域的位置还需要结合具体版本判断。

通用表空间与撤销表空间与临时表空间#

通用表空间允许多个表共享同一表空间,不能与一表一文件的布局混同。撤销表空间组织撤销日志,为事务回滚和一致性读重建历史版本提供信息;临时表空间则服务于相应临时表活动,不是保存持久业务行的替代位置。这几类名称表示用途与生命周期的差异,并不意味着每次更新都会向所有类型的文件各写一份相同数据。

双写缓冲区与重做日志#

双写保留完整页副本与重做日志记录页修改的职责对照

原理示意:启用完整双写保护时,脏页先进入双写区域,再写入数据文件的最终位置,以便在页写入中断时取得完整副本。重做日志则记录必要的修改,用于崩溃恢复;二者不是同一种日志,也不是把日志简单复制两遍。双写区域的具体文件位置随版本变化,图中不固定文件名和个数。

后台线程#

后台工作把前台事务产生的状态逐步整理为可持续运行的存储结构:页面清理负责推动脏页刷新,清理历史版本的工作在旧版本不再被回滚或一致性读需要后回收相应信息,异步读写由相关后台机制协作处理。更改缓冲也可能延后合并;这些任务并非每次提交都同步执行完毕,不能从职责名称推断固定线程数或执行耗时。