SQLite 架构介绍与源码解析

SQLite 是一款广泛使用的嵌入式关系型数据库管理系统,以其轻量级、易用和高效著称。它被广泛应用于移动设备、浏览器、嵌入式系统等场景。本文将详细介绍 SQLite 的架构,并结合其源码解析,帮助您深入理解其内部工作原理。


目录

  1. SQLite 总体架构
  2. 核心组件详解
  3. SQLite 工作流程
  4. 源码解析
  5. 总结

SQLite 总体架构

SQLite 的架构设计可分为以下几个层次:

  1. 编译器(Compiler):解析和分析 SQL 语句,生成中间代码。
  2. 虚拟数据库引擎(Virtual Database Engine, VDBE):执行编译器生成的中间代码。
  3. 后端存储引擎:包括 B-Tree 模块、Pager 模块和 OS 接口层,负责数据的存储和检索。
SQLite 架构图

核心组件详解

编译器

功能:

  • 解析 SQL 语句,将其转换为内部表示(抽象语法树,AST)。
  • 进行语法和语义检查。
  • 生成 VDBE 可执行的字节码指令。

流程:

  1. 词法分析(Lexing):将输入的 SQL 文本分解为标记(tokens)。
  2. 语法分析(Parsing):根据 SQLite 的语法规则,生成抽象语法树。
  3. 语义分析(Analyzing):检查语义错误,如表不存在、字段类型不匹配等。
  4. 代码生成(Code Generation):将语法树转换为 VDBE 字节码指令序列。

虚拟机(VDBE)

功能:

  • SQLite 的核心执行引擎,负责执行编译器生成的字节码。
  • 类似于解释器,逐条执行指令,完成数据库操作。

特点:

  • 指令集针对数据库操作进行了优化,如 OpenReadColumnSetNumColumns 等。
  • 使用栈式计算模型,操作数通常保存在栈中。

B-Tree 模块

功能:

  • 管理数据库文件的逻辑组织,以 B-Tree 结构存储表和索引。
  • 提供高效的数据插入、删除、查找和遍历操作。

特点:

  • 每个表和索引都对应一个 B-Tree。
  • 支持事务和并发控制。

Pager 模块

功能:

  • 管理数据库文件的读写,提供页级别的缓存机制。
  • 实现事务的原子性、一致性、隔离性和持久性(ACID)。

特点:

  • 使用缓存页(Cache Page)来减少磁盘 I/O。
  • 实现了日志(Write-Ahead Logging, WAL)和回滚机制。

OS 接口层

功能:

  • 抽象底层操作系统的文件和锁机制,提供统一的接口。
  • 使 SQLite 能够在不同操作系统上运行。

特点:

  • 包含文件读写、文件控制、内存分配、时间获取等接口。

SQLite 工作流程

  1. 输入 SQL 语句:用户输入一条 SQL 语句。
  2. 编译器处理:编译器解析 SQL,生成 VDBE 字节码。
  3. 执行字节码:VDBE 虚拟机执行字节码指令。
  4. 调用 B-Tree 和 Pager:根据指令,调用 B-Tree 和 Pager 模块进行数据操作。
  5. 数据存取:通过 OS 接口层,进行磁盘文件的读写操作。
  6. 返回结果:将查询结果返回给用户。

源码解析

源代码结构

SQLite 的源代码主要由以下几个部分组成:

  • src/:核心源码目录。
  • vdbe.c:虚拟机实现。
  • parse.y:SQL 语法解析器的 yacc 源文件。
  • btree.c:B-Tree 模块实现。
  • pager.c:Pager 模块实现。
  • os_unix.cos_win.c:OS 接口层的不同平台实现。

关键数据结构

Parse

用于存储解析过程中的上下文信息。

1
2
3
4
5
6
typedef struct Parse {
sqlite3 *db; /* The database connection */
int nErr; /* Number of errors seen */
Vdbe *pVdbe; /* An engine for executing database bytecode */
// 其他字段...
} Parse;

Vdbe

表示虚拟机实例。

1
2
3
4
5
6
typedef struct Vdbe {
sqlite3 *db; /* The database connection */
Op *aOp; /* Array of operations */
int nOp; /* Number of instructions in the program */
// 其他字段...
} Vdbe;

Btree

表示一个 B-Tree 对象。

1
2
3
4
5
6
typedef struct Btree {
sqlite3 *db; /* The database connection */
Pager *pPager; /* The pager associated with this B-Tree */
BtShared *pBt; /* Shared data for the B-Tree */
// 其他字段...
} Btree;

Pager

用于管理页面缓存和磁盘 I/O。

1
2
3
4
5
6
typedef struct Pager {
sqlite3_vfs *pVfs; /* OS interface */
int fd; /* File descriptor */
Pgno dbSize; /* Number of pages in the database */
// 其他字段...
} Pager;

执行 SQL 语句的过程

  1. 解析阶段(Parser)

    • 文件parse.y
    • 作用:使用 LALR(1) 文法规则解析 SQL 语句,构建抽象语法树(AST)。
  2. 语义分析和代码生成

    • 文件build.cexpr.cselect.c
    • 作用:对 AST 进行语义检查,并生成对应的 VDBE 字节码。
  3. 字节码执行(VDBE)

    • 文件vdbe.c
    • 作用:逐条执行字节码指令,完成数据库操作。

    示例:

    • 指令 OpenRead:打开一个 B-Tree 以供读取。
    • 指令 Column:从结果集中取出一列数据。
    • 指令 ResultRow:将结果返回给客户端。
  4. 存储引擎操作

    • B-Tree 模块

      • 文件btree.c
      • 作用:执行对 B-Tree 的增删改查操作。
    • Pager 模块

      • 文件pager.c
      • 作用:管理页面缓存、事务和日志。
  5. 文件 I/O 操作

    • 文件os_unix.cos_win.c
    • 作用:封装底层文件系统的操作,实现跨平台兼容。

示例:执行简单的 SELECT 语句

假设执行以下 SQL 语句:

1
SELECT name FROM users WHERE age > 30;

1. 解析和代码生成

  • 解析器将 SQL 文本转换为语法树。

  • 代码生成器根据语法树生成字节码,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    0: OpenRead     0, rootPageOfUsersTable
    1: Rewind 0
    2: Column 0, "age"
    3: GreaterThan 30
    4: IfNot Jump to 7
    5: Column 0, "name"
    6: ResultRow
    7: Next 0, Jump to 2
    8: Close 0
    9: Halt

2. 字节码执行

  • OpenRead:打开 users 表对应的 B-Tree。
  • Rewind:将游标指向第一条记录。
  • 循环执行
    • Column:获取当前记录的 age 字段。
    • GreaterThan:判断是否大于 30。
    • IfNot:如果不满足条件,跳转到 Next
    • Column:获取 name 字段。
    • ResultRow:输出结果行。
    • Next:移动到下一条记录,循环执行。

3. 数据存取

  • B-Tree 模块根据游标位置,读取对应的页面。
  • Pager 模块从缓存或磁盘中读取页面数据。
  • OS 接口层执行实际的文件 I/O 操作。

总结

SQLite 的架构设计精巧,将数据库操作分解为多个层次,每一层次都有明确的职责。通过编译器、虚拟机和存储引擎的协作,实现了对 SQL 语句的高效执行。理解 SQLite 的内部工作原理,有助于我们更好地使用和优化 SQLite 数据库。

关键点:

  • 模块化设计:各模块职责清晰,方便维护和扩展。
  • 虚拟机执行字节码:提高了执行效率,便于移植。
  • 高效的存储引擎:通过 B-Tree 和 Pager 模块,实现了高性能的数据存取。

参考资料:


https://withesse.co/post/sqlite-architecture-explanation-and-code-analysis/
Author
zt
Posted on
May 27, 2025
Licensed under