SQLite 内核:单文件 · Pager · B-Tree · VDBE · WAL · 锁
SQLite
是怎么做到十亿行每秒的 已经从性能叙事拆过 B-Tree
页面布局、WAL 与 Page Cache;PostgreSQL 内核
与 MySQL InnoDB
内核
讲清了服务器行存怎么用多进程、共享缓冲池和独立
WAL 撑并发。中间仍缺一层:一次
sqlite3_prepare_v2 + sqlite3_step
如何在进程内落到页面,Rollback Journal 与 WAL
如何改写并发与恢复,锁状态机到底允许什么并行。
本系列以 SQLite 3.45.x–3.46.x 为主线,写:
- 单文件格式、页面类型与 B-Tree 分裂。
- Pager / Page Cache 读改写契约。
- VDBE 字节码与 SQL 编译管线。
- Rollback Journal 与 WAL / checkpoint。
- 锁状态机、事务模式与隔离边界。
- 计划器、索引、ATTACH、完整性检查与在线备份。
- 与 PG / InnoDB / DuckDB / RocksDB 的选型收束。
系列状态:已完成(2026-07-18)。 全 17 篇已发布。规划见 PLAN.md。
版本锚定:SQLite 3.45.x–3.46.x 官方文档(Architecture、File Format、WAL、Locking)与源码。实验只使用实际运行过的 CLI / 绑定;不伪造跨库性能排名。
适合谁看
- 在移动端、桌面、边缘设备上嵌入 SQLite 的应用与平台工程师。
- 读完性能单篇,想从「为什么快」下沉到「路径怎么走」的读者。
- 从 PG / InnoDB 过来,想理解砍掉服务器层之后还剩什么的读者。
- 需要在 SQLite / DuckDB / RocksDB 之间做嵌入式选型的工程师。
在知识栈中的位置
| 层 | 站内内容 | 本系列关系 |
|---|---|---|
| 性能叙事 | sqlite-billion-rows | 第 1、3–4、8 篇回链,不复述 benchmark |
| 服务器行存 | postgresql-kernel、mysql-innodb | 第 16–17 篇对照 |
| LSM 嵌入 KV | rocksdb | 第 1、4、17 篇边界 |
| 列存 / 分析嵌入 | columnar-engine | 第 17 篇 DuckDB 边界 |
| FDB 历史借用 | foundationdb/12 | 第 4 篇回链 |
| SQLite 内核 | 本系列 | 单文件 → Pager → VDBE → 日志/锁 → 选型 |
一、这个领域最值得关注的 5 个问题
- 单文件 + 单写者约束下,一次
SELECT如何零 IPC 落到页面? → 第 1–5 篇。 - Rollback Journal 与 WAL 如何改变读写并发与恢复路径? → 第 7–8 篇。
- SQLite 的锁状态机允许什么级别的并行? → 第 9–10 篇。
- 无独立服务进程时,计划器与索引如何兑现「足够好」的 OLTP? → 第 11–12 篇。
- 何时选 SQLite 而非 PG / DuckDB / RocksDB? → 第 16–17 篇。
二、篇目依赖关系与推荐阅读路径
flowchart TD
A["01 Embedded overview"] --> B["02 File format"]
B --> C["03 Pager cache"]
C --> D["04 B-Tree"]
D --> E["05 VDBE"]
E --> F["06 SQL compile"]
C --> G["07 Rollback journal"]
G --> H["08 WAL checkpoint"]
H --> I["09 Locking"]
I --> J["10 Transactions"]
F --> K["11 Planner"]
D --> L["12 Indexes"]
K --> L
J --> M["13 ATTACH"]
H --> N["14 Integrity"]
N --> O["15 Backup"]
J --> P["16 PG InnoDB compare"]
L --> Q["17 Selection"]
P --> Q
O --> Q
| 路径 | 篇目 | 适合 |
|---|---|---|
| 必读核心 | 1 → 2 → 3 → 4 → 5 → 8 → 9 → 17 | 快速建立坐标系 |
| 持久化与并发 | 7 → 8 → 9 → 10 → 14 | 写路径 / 锁读者 |
| 执行与计划 | 5 → 6 → 11 → 12 | 查询路径读者 |
| 对照选型 | 1 → 16 → 17 | 从 PG/InnoDB 过来 |
| 完整通读 | 1 → … → 17 | 系统掌握 |
三、目录与每篇价值点
第一部分:全景与存储路径
- 嵌入式行存全景:单文件、单写者、零
IPC
- 生态位地图;与性能单篇、服务器行存、LSM 分工;17 篇路线。
- 单文件格式与页面头
- Database header、page size、页类型;file format 锚点。
- Pager 与 Page
Cache
- 读改写契约、脏页与缓存边界。
- B-Tree
遍历与分裂
- 表/索引 B-Tree、cell 布局;Bayer & McCreight 谱系。
- VDBE
字节码执行
sqlite3_step循环、寄存器与游标。
第二部分:编译与日志
- SQL
编译管线
prepare→ 分析 → 代码生成。
- Rollback
Journal 模式
- 写时拷贝、提交点与 journal 变体。
- WAL 与
checkpoint
-wal/-shm、帧格式、checkpoint 策略。
第三部分:并发与事务
- 锁状态与
shared cache
- SHARED → RESERVED → PENDING → EXCLUSIVE。
- 事务与隔离
- DEFERRED/IMMEDIATE/EXCLUSIVE;与 ANSI 隔离对照。
第四部分:计划、索引与多库
- 查询计划器与统计
sqlite_stat*、代价估计、EXPLAIN QUERY PLAN。
- 索引与
covering scan
- 覆盖索引与自动索引边界。
- ATTACH /
多库边界
- 跨库事务与「单文件」叙事的张力。
第五部分:完整性、备份与选型
- 完整性检查与损坏恢复
PRAGMA integrity_check与修复边界。
- 在线备份与
sqlite3_backup
- Hot copy API 与文件级拷贝的语义差。
- 与
PG / InnoDB 机制对照
- 进程、WAL、锁、缓冲池对照;不写排名。
- 选型与阅读地图
- SQLite vs PG vs DuckDB vs RocksDB;系列收束。
四、与相邻系列的分工
| 话题 | 本系列 | 相邻内容 |
|---|---|---|
| 为何「看起来快」 | 第 1、3–4、8 篇回链 | sqlite-billion-rows |
| 服务器行存内核 | 第 16–17 篇对照 | postgresql-kernel、mysql-innodb |
| LSM 写优化 | 第 4、17 篇边界 | rocksdb |
| 列存分析 | 第 17 篇 DuckDB 一句 | columnar-engine |
| FDB 借用 SQLite B-Tree | 第 4 篇回链 | foundationdb/12 |
参考
返回 数据库索引 · sqlite-billion-rows · postgresql-kernel
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【SQLite 内核】嵌入式行存全景:单文件、单写者、零 IPC
定位单文件嵌入式行存在服务器行存与 LSM 嵌入 KV 之间的生态位;钉住 SQLite 架构约束、站内分工与 17 篇阅读路线,并以 Bayer/McCreight、官方 file format、PVLDB 2022 为学术锚点。
【SQLite 内核】Pager 与 Page Cache
拆解 Pager 作为 B-Tree 与操作系统文件之间的契约层:page cache 命中/未命中路径、脏页生命周期与提交前的可回滚保证,并与 PG shared_buffers、InnoDB Buffer Pool 的跨进程共享模型对照。
【SQLite 内核】单文件格式与页面头
拆解 SQLite 单文件格式:100 字节 database header 与 B-Tree 页面头的逐字段布局,用本机 3.53.2 CLI 实测 hexdump 核对 magic、page size、页类型标志,并钉住 file format 官方规范与 Bayer/McCreight 谱系。
【SQLite 内核】B-Tree 遍历与分裂:表 B-Tree、索引 B-Tree 与 cell 布局
钉住 SQLite table b-tree 与 index b-tree 的字节布局差异、cell pointer array 如何做到逻辑有序物理可乱序、overflow 阈值与 balance() 分裂/合并触发条件;源码以 btree.c 函数签名为准,学术锚点是 Bayer & McCreight 1972。