土法炼钢兴趣小组的算法知识备份

【SQLite 内核】嵌入式行存全景:单文件、单写者、零 IPC

文章导航

分类入口
databasestorage
标签入口
#sqlite#embedded#row-store#pager#btree#vdbe#wal#single-writer#file-format

源码下载

本文相关源码已整理,共 11 个文件。

打开下载目录 →

目录

一次进程内点查:sqlite3_prepare_v2(db, "SELECT … WHERE id=?", …),再循环 sqlite3_step(stmt),没有 socket、没有连接池线程、没有独立数据库守护进程。调用栈从应用代码直接进入解析/字节码(或复用已 prepare 的 VDBE 程序),再经 Pager 取页、B-Tree 定位到记录。同一条 SQL 若走 PostgreSQL,则至少多出协议编解码、backend 进程调度与共享缓冲池上的锁协作——那是服务器行存为网络并发付出的固定税。

SQLite 是怎么做到十亿行每秒的 已经从性能叙事拆过页面布局、WAL 与 Page Cache;PostgreSQL 内核InnoDB 内核 讲清了服务器怎么做行存。中间仍缺一层:嵌入式约束如何塑造内核路径,以及后续 17 篇如何把路径钉死。本文是「SQLite 内核」系列第 1 篇,只做三件事:

  1. 画出进程内 HashMap、SQLite、DuckDB、RocksDB、PG/InnoDB 的生态位地图。
  2. 用官方架构文档钉住「单文件 · 单写者 · 页式 B-Tree · VDBE」四条约束,并交代学术谱系与开放问题。
  3. 给出与站内系列的分工,以及 17 篇阅读路线。

本文是「SQLite 内核」系列第 1 篇(共 17 篇)。→ 系列目录

篇目 核心内容
第 1 篇 · 嵌入式行存全景 生态位、架构约束、系列路线
第 2 篇 · 单文件格式与页面头 Database header、page size、页类型
第 3 篇 · Pager 与 Page Cache 读改写契约与脏页

版本锚定:SQLite 3.45.x–3.46.x 官方文档(Architecture of SQLiteFile Format For SQLite DatabasesWrite-Ahead LoggingFile Locking And Concurrency In SQLite Version 3);源码以 amalgamation / 拆分树中的 pager.cbtree.cvdbe*.cwal.c 为准。本文不复述 SQL 语言手册,也不展开 FTS / JSON 扩展。


一、一次点查:零 IPC 意味着什么

站内性能单篇用图对比了 MySQL/InnoDB 与 SQLite 的调用链深度。本系列直接复用该图,避免另绘一套口径不同的路径图:

MySQL 与 SQLite 查询路径对比

图意:服务器路径要把请求送进独立进程并经过缓冲池协作;SQLite 路径把「连接」收成库内指针,热路径是函数调用。

1.1 三条可核对的工程后果

后果 机制含义 本系列落点
没有网络协议栈 无握手、无编解码、无连接线程池 第 5–6 篇:prepare/step
没有跨进程共享缓冲池 Page Cache 在本连接/本进程语义下工作;多进程靠 OS 文件锁协调 第 3、9 篇
写者数量有硬边界 同一数据库文件同一时刻通常只有一个写者(锁状态机保证) 第 9–10 篇

官方 Architecture of SQLite 把 SQLite 描述为嵌入到应用进程中的库,而不是独立服务器。这不是营销口号:它直接删掉了「服务端进程模型」这一整层,换来延迟与部署简单性,也换来不能把 PG 的并发心智模型原样搬过来

1.2 生态位:五格对照

flowchart TB
  subgraph inproc ["In-process"]
    HM["Language HashMap"]
    SQL["SQLite<br/>SQL + B-Tree pages"]
    DUCK["DuckDB<br/>analytical embed"]
    RK["RocksDB<br/>LSM KV embed"]
  end
  subgraph server ["Client or server"]
    PG["PostgreSQL / InnoDB<br/>multi-process row store"]
  end
  HM -->|"need SQL / durability"| SQL
  SQL -.->|"heavy analytics"| DUCK
  SQL -.->|"raw KV no SQL"| RK
  SQL -->|"need multi-writer network"| PG
形态 接口 存储范式 典型约束 站内入口
语言内 Map put/get 堆对象 无跨进程、无 SQL architecture/17
SQLite SQL / C API 页式 B-Tree 单文件 单写者、嵌入式 本系列
DuckDB SQL 列存 / 向量化 分析为主 columnar-engine 边界
RocksDB KV API LSM 无 SQL 引擎 rocksdb
PG / InnoDB SQL + 网络 行存 + 服务器缓冲池 多写者、运维面大 postgresql-kernelmysql-innodb

一句话:SQLite 占住的是「需要 SQL 与事务语义、但不想(或不能)跑独立数据库进程」的那一格——手机本地库、桌面应用、边缘设备、许多测试夹具与小型服务内嵌状态。


二、四条架构约束(后续章节的坐标系)

官方架构与 file format 文档反复出现的约束,可收成四条。本系列每一篇都应能回指其中至少一条。

2.1 单文件(可 cp 的数据库)

主库是一个普通文件(加上 journal 或 -wal/-shm 附属文件)。File Format For SQLite Databases 规定了页大小、页类型与 B-Tree 在页内的布局。运维上的好处是备份与拷贝心智简单;代价是「库」与「文件生命周期」绑死——损坏、部分写、错误的热拷贝都会直接打在文件格式上(第 14–15 篇)。

2.2 单写者(锁状态机,不是「完全单线程」)

File Locking And Concurrency 定义锁阶梯:多个读者可持 SHARED;写路径升到 RESERVED / PENDING / EXCLUSIVE。「单写者」指同一数据库文件上的写互斥,不是「整个进程只能跑一个线程」。 多线程多连接可以并存,但写锁仍按文件粒度串行化写事务。第 9–10 篇展开;本篇只钉住:并发模型与 PG 行级锁不是同一物种。

2.3 页式 B-Tree(不是 LSM)

表与索引落在 B-Tree 页上(Bayer & McCreight, 1972 奠基;SQLite file format 给出工程字节布局)。这与 RocksDB 的 LSM(O’Neil et al., 1996)分叉:随机点查与短事务通常站在页式索引一侧;高吞吐顺序写与压缩策略站在 LSM 一侧。本系列不写跨范式吞吐排名,只在第 4、17 篇谈职责边界。

FoundationDB 早期 Storage 引擎曾借用 SQLite 派生的 B-Tree(见 foundationdb/12 Redwood)——那是分布式 KV 对页式引擎的取用史,不是本系列要重写的 SQLite SQL 层。

2.4 VDBE(SQL 编译成字节码再执行)

SQL 文本不在热路径上反复「解释执行」:sqlite3_prepare_v2 生成 VDBE 程序,sqlite3_step 推进虚拟机。官方 The VDBEArchitecture 把这层定位为可移植执行引擎。第 5–6 篇拆字节码与编译管线;本篇只强调:嵌入式并不等于「没有执行引擎」——它把执行引擎链进了应用进程。

flowchart LR
  sql["SQL text"] --> prep["prepare_v2"]
  prep --> vdbe["VDBE program"]
  vdbe --> step["sqlite3_step loop"]
  step --> pager["Pager"]
  pager --> btree["B-Tree pages"]
  btree --> file["Database file"]
  step -.->|"writes"| journal["Journal or WAL"]
  journal --> file

三、与站内系列的分工

话题 已有内容 本系列怎么用
为何延迟低、页面如何布局 sqlite-billion-rows 回链性能叙事与 SVG;不复述 speedtest/1BRC 数字为新测
服务器行存:进程、MVCC、WAL postgresql-kernelmysql-innodb 第 16 篇机制对照;第 17 篇选型
LSM 嵌入 KV rocksdb 第 4、17 篇边界:无 SQL / 写放大模型不同
列存分析嵌入 columnar-engine 第 17 篇 DuckDB 边界句
隔离级别概念 mvcc 第 10 篇引用 Berenson,不重写 PG CLOG
FDB 借用 B-Tree foundationdb/12 第 4 篇一句历史回链

一句话:性能单篇回答「约束如何换速度」;PG/InnoDB 回答「服务器如何换并发」;本系列回答「嵌入式行存内核路径如何组织」。

常见误解

  1. 「SQLite 没有并发。」
    多读者可并行;WAL 模式下读者与写者可更好重叠(官方 WAL 文档)。没有的是「多个写者同时改同一库文件」的默认模型,不是零并发。

  2. 「SQLite 只是玩具 / 不能上生产。」
    嵌入式生产面极广(移动 OS、浏览器、桌面应用、设备固件)。「能否生产」取决于工作负载是否匹配单写者与单机文件语义,不是玩具标签。Gaffney et al.(PVLDB 2022)从工程与分析负载两侧讨论其现状与瓶颈,本系列第 17 篇收选型,不在此用营销句替代。

  3. 「SQLite 的 WAL 等于 PostgreSQL 的 WAL。」
    名字相同,语义不同:SQLite WAL 是单文件库上的写前日志与 checkpoint 协议;PG WAL 服务服务器集群的崩溃恢复与复制。第 8、16 篇对照,禁止把运维经验直接平移。

  4. 「嵌入 RocksDB 就能替代 SQLite。」
    RocksDB 提供持久 KV 与迭代器,不提供 SQL、优化器与表约束。需要声明式查询与事务 SQL 时,缺的是引擎层,不是「再快一点的 Map」。


四、学术谱系、工程间隙与开放问题

4.1 谱系(奠基 → 工程定义 → 近期讨论)

阶段 代表 work 与本系列关系
有序索引范式 Bayer & McCreight, Organization and Maintenance of Large Ordered Indexes, Acta Informatica, 1972 第 4 篇 B-Tree 的问题定义锚点
日志结构写优化分叉 O’Neil et al., The Log-Structured Merge-Tree, Acta Informatica, 1996 与 RocksDB 对照轴;本系列站在页式一侧
隔离级别词汇 Berenson et al., A Critique of ANSI SQL Isolation Levels, SIGMOD 1995 第 10 篇事务/隔离用语;链 mvcc
工程规范(A 级) SQLite File Format / Locking / WAL / Architecture 第 2–10 篇机制正文的直接来源
近期系统讨论 Gaffney, Prammer, Brasfield, Hipp, Kennedy, Patel. SQLite: Past, Present, and Future. PVLDB 15(12), 2022. DOI: 10.14778/3554821.3554842 嵌入式 SQL 在分析负载上的瓶颈与演进;第 1、17 篇引用其问题框架,不把论文内实验数字冒充本站实测

4.2 工程间隙

论文与官方文档描述的是可移植 C 库在 POSIX/Windows 文件语义上的行为;生产中还叠了:

本系列默认 本地 POSIX 文件系统上的推荐部署;非常规文件系统只在排障/选型篇点边界,不假装处处等价。

4.3 开放问题(有文献线索,本系列不关闭)

  1. 单写者是否应让位于页级锁?
    官方长期选择文件级写互斥以换实现简单与损坏面可控;细粒度锁会靠近服务器引擎复杂度。争论存在于社区与扩展方案中,本系列按官方主线写,第 9–10 篇标注边界。

  2. WAL 默认化之后,checkpoint 与读放大如何治理?
    WAL 改善读写重叠,但 checkpoint 策略与 -wal 增长是运维面(第 8 篇)。无本站新测时,只给机制与官方旋钮,不给「最佳 PRAGMA 配方」。

  3. 嵌入式 SQL 与分析负载的分工。
    Gaffney et al.(PVLDB 2022)讨论 SQLite 在分析场景上的瓶颈与优化方向;DuckDB 等列存嵌入式从另一侧切入。第 17 篇给选型决策树,不宣称其中一方将统一嵌入式 SQL


五、17 篇阅读地图

flowchart TD
  A["01 Overview"] --> B["02 Format"]
  B --> C["03 Pager"]
  C --> D["04 B-Tree"]
  D --> E["05 VDBE"]
  E --> F["06 Compile"]
  C --> G["07 Journal"]
  G --> H["08 WAL"]
  H --> I["09 Locks"]
  I --> J["10 Txn"]
  F --> K["11 Planner"]
  D --> L["12 Indexes"]
  J --> M["13 ATTACH"]
  H --> N["14 Integrity"]
  N --> O["15 Backup"]
  J --> P["16 PG/InnoDB"]
  P --> Q["17 Selection"]
  L --> Q
  O --> Q
路径 建议篇目 目标
必读核心 1 → 2 → 3 → 4 → 5 → 8 → 9 → 17 建立坐标系并会选型
持久化深读 7 → 8 → 9 → 10 → 14 → 15 写路径、锁、损坏与备份
从 PG 过来 1 → 16 → 8 → 9 → 17 先对照再下沉
完整通读 1 … 17 系统掌握

系列规划与实验台账见 PLAN.md;实验脚本放在 reproduce/


六、小结

三句话小结

  1. SQLite 占住「需要 SQL/事务、但嵌入应用进程」的生态位:单文件、页式 B-Tree、VDBE 执行、文件级写互斥——与 PG/InnoDB 服务器行存、RocksDB LSM、DuckDB 分析嵌入式分工清晰。
  2. 零 IPC 换来的是调用链变短,不是「没有引擎」;后续篇章按 Pager → B-Tree → VDBE → Journal/WAL → 锁 → 计划 → 选型展开。
  3. 学术锚点是 Bayer & McCreight(B-Tree)、官方 file format/locking/WAL(工程定义)、Berenson(隔离词汇)、O’Neil LSM(对照分叉)、Gaffney et al. PVLDB 2022(近期嵌入式 SQL 讨论);单写者与分析负载分工仍是开放问题。

常见误解(收束)

上文第三节四条已覆盖「无并发 / 玩具 / WAL 等同 PG / RocksDB 可替代」;读完本篇后,把 SQLite 当成「小 PostgreSQL」或「带 SQL 的 HashMap」都会在第 8–10、16–17 篇被机制打脸。


参考资料

规范与官方文档(A 级)

  1. SQLite Documentation, Architecture of SQLite(sqlite.org)。
  2. SQLite Documentation, File Format For SQLite Databases(sqlite.org)。
  3. SQLite Documentation, Write-Ahead LoggingFile Locking And Concurrency In SQLite Version 3Atomic Commit In SQLite
  4. SQLite Documentation, The Virtual Database Engine (VDBE)Query Planning

论文(A 级)

  1. Bayer, R. & McCreight, E. Organization and Maintenance of Large Ordered Indexes. Acta Informatica, 1972。
  2. O’Neil, P., Cheng, E., Gawlick, D. & O’Neil, E. The Log-Structured Merge-Tree (LSM-Tree). Acta Informatica, 1996。
  3. Berenson, H., Bernstein, P., Gray, J., Melton, J., O’Neil, E. & O’Neil, P. A Critique of ANSI SQL Isolation Levels. SIGMOD 1995。
  4. Gaffney, K. P., Prammer, M., Brasfield, L., Hipp, D. R., Kennedy, D. & Patel, J. M. SQLite: Past, Present, and Future. PVLDB 15(12): 3535–3547, 2022. DOI: 10.14778/3554821.3554842。

站内

  1. SQLite 是怎么做到十亿行每秒的(性能叙事与路径对比图)。
  2. PostgreSQL 内核MySQL InnoDB 内核RocksDB 内核列存引擎
  3. 本系列 indexPLAN.md

上一篇系列目录
下一篇单文件格式与页面头

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-07-17 · database / storage

【SQLite 内核】单文件格式与页面头

拆解 SQLite 单文件格式:100 字节 database header 与 B-Tree 页面头的逐字段布局,用本机 3.53.2 CLI 实测 hexdump 核对 magic、page size、页类型标志,并钉住 file format 官方规范与 Bayer/McCreight 谱系。

2026-07-17 · database / storage

【SQLite 内核】Pager 与 Page Cache

拆解 Pager 作为 B-Tree 与操作系统文件之间的契约层:page cache 命中/未命中路径、脏页生命周期与提交前的可回滚保证,并与 PG shared_buffers、InnoDB Buffer Pool 的跨进程共享模型对照。


By .