第 8 章 · 01 页式存储:磁盘的统一管理单位


文档摘要

第 8 章 · 01 页式存储:磁盘的统一管理单位 本节摘要:造数据库的第一个问题:「数据存在哪里?」朴素答案「一个记录一个文件」在数据量大时灾难(文件系统开销、碎片)。数据库的解法是「页式存储」:把整个数据库存成一个文件,内部按固定大小的「页」(如 4KB)切分管理。本节讲清页的分配、空闲回收、页内紧凑存记录。理解页式存储,你就理解了所有存储引擎的共通骨架。 内容来源:基于数据库存储引擎整理的导读,呼应姊妹篇《Linux 命令》第 5 章磁盘与块。 学习目标 说清为什么用「页式存储」而非「一记录一文件」。 理解页(如 4KB)是数据库 IO 的最小单位。 描述页内如何存多条记录(记录 + 偏移表)。 理解空闲页管理与页分裂。

第 8 章 · 01 页式存储:磁盘的统一管理单位

本节摘要:造数据库的第一个问题:「数据存在哪里?」朴素答案「一个记录一个文件」在数据量大时灾难(文件系统开销、碎片)。数据库的解法是「页式存储」:把整个数据库存成一个文件,内部按固定大小的「页」(如 4KB)切分管理。本节讲清页的分配、空闲回收、页内紧凑存记录。理解页式存储,你就理解了所有存储引擎的共通骨架。

内容来源:基于数据库存储引擎整理的导读,呼应姊妹篇《Linux 命令》第 5 章磁盘与块。

学习目标

  1. 说清为什么用「页式存储」而非「一记录一文件」。
  2. 理解页(如 4KB)是数据库 IO 的最小单位。
  3. 描述页内如何存多条记录(记录 + 偏移表)。
  4. 理解空闲页管理与页分裂。

一、学习价值:存储引擎的根基

数据库与普通文件程序的根本差别,从存储层就开始了。「一记录一文件」看似直观,但在百万级记录时崩溃:打开/关闭文件开销、目录项爆炸、碎片。页式存储把所有数据放一个文件,按页管理——这是 SQLite、MySQL、PostgreSQL 的共通做法。理解它,你才理解「数据库为什么快」「为什么有页分裂」。

二、子系统拆解

为什么是页

  • IO 对齐:磁盘按块(扇区)读写,页大小对齐块(4KB = 8 个 512B 扇区),一次 IO 读一页,高效。
  • 统一管理:一个文件内按页编号(页 0、页 1...),读写都以页为单位。
  • 缓冲池:内存里缓存「热页」,读写先走内存,定期刷盘。

页内结构

一个页(4KB)内部如何存多条记录?常见布局:

[页头: 元信息] [空闲空间] [记录3] [记录2] [记录1] [偏移表: 指向每条记录的位置] ↑ 新记录从这里往下长 ↑ 从页尾往页头长

记录从页尾向页头生长,偏移表从页头后向页尾生长,中间是空闲。新增记录:写到空闲区、偏移表加一条指向它。

空闲页管理

数据库文件增长时,分配新页(文件追加)。删除记录只标记(或整理),页可能变「稀疏」。空闲页用空闲链表或位图管理,后续插入复用。

页分裂(B+树用到)

当某页满了还要插入,触发页分裂:把页一分为二,各占一半。这是 B+树(下一节)的关键机制。

三、上手第一步

  1. 实现最简页式存储:固定页大小,每页能存若干记录。
  2. 实现读写页(pread/pwrite 按页偏移)。
  3. 实现页内记录的增删(偏移表)。
  4. 验证:插几百条记录,close 后 reopen,数据还在。

本节要点回顾

  1. 页式存储:整个数据库一个文件,按固定页(如 4KB)切分,IO 以页为单位。
  2. 理由:IO 对齐、统一管理、便于缓冲池。
  3. 页内:页头+空闲+记录(从尾长)+偏移表(从头长)。
  4. 空闲页:链表/位图管理复用;页分裂:页满时分两页(B+树用)。

推荐上手顺序

  1. 实现固定页大小 + 按偏移读写。
  2. 页内记录布局(偏移表)。
  3. 增删查记录,验证持久化。
  4. 下一节:B+树索引。

下一节讲 B+树——数据库的标准索引结构。


发布者: 作者: 灏天文库 转发
评论区 (0)
U