深入 SQLite 后端:虚拟机、存储和构建过程

发布: (2026年1月11日 GMT+8 20:00)
4 min read
原文: Dev.to

Source: Dev.to

虚拟机 (VDBE)

当前端完成编译后,会把字节码程序交给虚拟数据库引擎 (VDBE)。

字节码程序是:

  • 一系列线性指令
  • 每条指令包含一个操作码和最多五个操作数
  • 按顺序执行,一次一条指令

该 VM 的行为类似于专为数据库操作设计的自定义 CPU,负责表扫描、值比较、光标管理以及事务语义的实现等工作。

树模块(B‑树存储)

SQLite 使用树结构来存储数据:

  • → B+ 树
  • 索引 → B‑树

每个表和索引都有各自独立的树结构。实现代码位于:

  • btree.c – 树的逻辑
  • btree.h – 公共接口

树模块支持搜索、插入、删除、更新以及结构性变更(例如创建或删除表和索引)。

Pager(页面管理器)

Pager 是一个关键组件,负责调解所有文件 I/O。树模块从不直接访问数据库文件,而是通过 Pager 请求固定大小的页面。

Pager 的主要职责:

  • 读取和写入数据库页面
  • 维护内存页面缓存
  • 处理文件锁定
  • 管理回滚日志(journal)
  • 强制事务边界

实际上,Pager 同时充当 数据管理器锁管理器日志管理器事务管理器。其源文件为:

  • pager.c
  • pager.h

Pager 使 SQLite 能够在单个数据库文件上提供 ACID 保证。

lovestaco@i3nux-mint:~/pers/sqlite$ ll /home/lovestaco/pers/sqlite/bld/sqlite3
-rwxrwxr-x 1 lovestaco lovestaco 6.9M Jan 11 17:14 /home/lovestaco/pers/sqlite/bld/sqlite3

构建过程

SQLite 的构建过程体现了其自包含和可复现的哲学。整个过程分为六个主要步骤:

  1. 生成 sqlite3.h
  2. 构建 SQL 解析器
  3. 生成 VM 操作码
  4. 生成操作码名称
  5. 生成 SQL 关键字表
  6. 编译库文件

在构建期间:

  • lemon.c 生成 parse.cparse.h
  • mkkeywordhash.c 生成 keywordhash.h
  • awksed 生成 sqlite3.hopcodes.hopcodes.c

opcodes.h 为 VM 指令分配数值,而 opcodes.c 将操作码映射为人类可读的名称,便于调试和诊断。

现代发行版提供了一个合并文件 sqlite3.c,以及 sqlite3.h。使用合并文件的优势包括:

  • 性能提升 5–10 %
  • 更激进的编译器优化
  • 构建过程更简化
  • 更易嵌入到应用程序中

命令行工具还需要 shell.c

小结

  • SQL 被编译成字节码,由专门构建的 VM 执行。
  • SQLite 通过数据库级锁实现可串行化执行。
  • 日志机制保证原子性和恢复能力。
  • 每个数据库都存放在单个本地文件中,由 sqlite_master 锚定。

该架构模块化、层次清晰,且完全开源、属于公有领域。

展望

下一章节将更深入地探讨数据库和日志文件的存储结构,揭示 SQLite 磁盘布局是如何实现这些抽象的。

进一步资源

  • 我的 SQLite 实验:
  • FreeDevTools(开源开发工具中心):

参考:SQLite Database System: Design and Implementation. Sibsankar Haldar (n.d.).

Back to Blog

相关文章

阅读更多 »