You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中B+树节点是如何序列化存储到磁盘文件的?

B+树节点在MySQL磁盘文件中的序列化与存储逻辑

以最常用的InnoDB引擎为例,它对B+树的磁盘存储有一套成熟的实现规则:

基础存储单元:页

InnoDB不管是共享表空间ibdata1,还是开启innodb_file_per_table参数后每个表对应的独立.ibd文件,全部按照固定大小的页来管理存储空间,默认页大小为16KB,B+树的每个节点就对应一个物理页。

节点序列化规则

每个页的内容按照固定结构序列化写入磁盘,整体分为头部元数据、存储内容区、尾部校验和三部分:

  • 页头部占固定38字节,存储元信息:包括当前页号、页类型(区分是B+树非叶子节点、叶子节点、undo页还是系统页等)、同层相邻的上一个/下一个页号(对应B+树叶子节点的双向链表逻辑)、当前页已存储的记录数、页的空闲空间偏移等。所有元字段都按照固定字节长度、统一字节序写入,读取的时候直接按偏移量解析即可。
  • 非叶子节点内容区按顺序存储索引条目:每个条目结构为「索引键值 + 子节点页号」,条目长度根据索引字段类型计算,变长字段会额外存储长度标识。
  • 聚簇索引叶子节点内容区存储完整的行数据:每条记录包括行头、隐藏字段(事务ID、回滚指针、主键)、用户定义的列值,变长列会在记录头部存储长度偏移列表。
  • 二级索引叶子节点内容区存储的条目为「索引键值 + 对应聚簇索引主键值」。

单文件寻址逻辑

所有页在表空间文件中的位置由页号直接映射:默认配置下,页号为N的页,在单文件中的起始偏移量为N * 16KB,数据库可以直接通过这个偏移量调用pread/pwrite类系统调用定位到对应位置读写,不需要遍历整个文件,因此所有B+树节点可以整齐排列在同一个磁盘文件中。

关于随机访问的问题

你判断的没错,原生B+树的读写逻辑确实不可避免随机访问,但InnoDB做了大量优化来降低随机IO的开销:

  • 首先是Buffer Pool内存缓存:热点页会长期驻留内存,读写操作优先命中缓存,不需要每次都访问磁盘。
  • 写入操作通过WAL机制优化:更新操作先写顺序写入的redo log记录变更,再异步将内存中的脏页批量刷回磁盘,把大量随机写转化为顺序写,降低延迟。
  • 非唯一二级索引的插入/更新操作通过Change Buffer优化:不需要立刻读取对应的索引叶子节点到内存,先将变更记录在Change Buffer中,后台异步批量合并到磁盘节点,减少随机读次数。
  • 预读机制:顺序查询时会提前加载相邻的页到缓存,大范围扫描时几乎不需要额外随机读。

内容的提问来源于stack exchange,提问作者mrpre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:36:04