【免费下载链接】stoolap
A Modern Embedded SQL Database written in Rust
Stoolap 是一款用 Rust 编写的现代嵌入式 SQL 数据库(Embedded SQL Database),它最大的设计亮点之一,是存储引擎采用了「热缓冲 + 冷列式 Volume」的分层架构:写入走内存中的行式热缓冲,读取则命中磁盘上不可变的列式冷数据,两者透明合并。这套设计借鉴了 Iceberg、Delta Lake 等数据湖的 Manifest/Tombstone 思想,又比传统 LSM 树更简单,让 OLTP 与 OLAP 负载在单机嵌入式数据库里同时跑出好性能。本文将带你用一篇的篇幅看懂它的完整分层机制。
为什么不用纯行式或纯列式?
大多数数据库只选一种存储格式:PostgreSQL 处处行式,DuckDB 处处列式。行式利于点查和更新,列式利于批量扫描和聚合——鱼和熊掌能否兼得?
Stoolap 的答案是经典的Delta-Main 分层架构(类似 SAP HANA、SingleStore 的思路):
| 层级 | 格式 | 优化目标 |
|---|---|---|
| 🔥 Hot Buffer(热缓冲) | 行式 + MVCC 版本链 | 高频写入、点查、事务隔离 |
| ❄️ Cold Volume(冷段) | 不可变列式.vol文件 | 分析扫描、聚合下推、快速启动 |
查询引擎在扫描时自动把两层数据透明合并,用户完全无感知。这种「写入行式、读取列式」的组合,正是它无需分布式系统就能兼顾两类负载的关键。
热缓冲(Hot Buffer):行式 + MVCC 的版本世界
所有 INSERT、UPDATE、DELETE 都先落在热缓冲中。它的核心特征:
- 行式存储:一条记录是一个完整的 Row,便于随机读写;
- 完整版本链:每次修改都生成新版本而非覆盖,通过
prev指针串成版本链,配合事务 ID 做 MVCC 可见性判断,读操作永不阻塞写操作; - 索引只覆盖热数据:B-tree、Hash、Bitmap 二级索引仅服务热缓冲中的行,避免在百万级不可变冷行上维护索引的开销(HNSW 向量索引是唯一例外)。
关于版本链、隔离级别与可见性规则的更多细节,可参考官方文档 mvcc-implementation.md。
冷列式 Volume:不可变的分析加速层
当一张表积累到足够多的已提交行(首次 10 万行,之后每 1 万行触发增量封冻),后台 checkpoint 线程会把热缓冲中的行Seal(封冻)成不可变的列式文件vol_XXXXXXXX.vol,存放在volumes/<table>/目录下。
每个冷 Volume 自带一套查询加速设施:
| 加速技术 | 作用 |
|---|---|
| Zone Map | 每列、每 6.4 万行组记录 min/max,WHERE 条件命不中的行组直接跳过 |
| Bloom Filter | 文本列等值判断的快速拒绝 |
| 字典编码 | GROUP BY/DISTINCT直接从字典提取去重值,内层循环零哈希 |
| CRC32 校验 | 尾部校验和,损坏即被发现 |
| 列式聚合下推 | SUM/COUNT/MIN/MAX/AVG 直接在原始 i64/f64 数组上累加,不构造任何 Row/Value 对象 |
磁盘上的目录结构一目了然:
/path/to/database/ db.lock wal/ wal_000001.log # 预写日志 volumes/ table_name/ vol_00064d50e5946141.vol # 封冻的冷段 vol_00064d50e5946141.sidx # 该冷段的二级索引旁挂文件 manifest.bin # 段清单:volume列表、tombstone、checkpoint LSN受 Iceberg 启发的关键设计:Manifest + Tombstone
Stoolap 与 Iceberg、Delta Lake 一脉相承的地方,在于用清单(Manifest)管理数据文件:
- manifest.bin 按表持久化:记录该表所有冷段列表、tombstone 与 checkpoint LSN,通过「先 fsync 再原子 rename」落盘,与 Iceberg 的 manifest list 角色对应;
- 版本化 Tombstone:删除或更新冷行时,不重写数据文件,而是记录一个
(row_id, commit_seq)对。快照事务在begin_seq=N时只能看到commit_seq <= N的 tombstone——老快照因此仍能看到原冷行,快照隔离由此免费获得; - Compaction 合并冷段:只有「偏小」「超限」「带 tombstone」的段才会被重写合并,干净的达标段永久冻结、绝不重写,把磁盘 I/O 压到最低。
这比 Delta Lake 的写时复制(重写整个数据文件)和 Iceberg 的独立 position-delete 文件都更轻量:tombstone 的可见性判断被直接内联进扫描路径。
唯一的不变式:「最新来源获胜」
Stoolap 去重逻辑简单到只有一条规则:
对任意 row_id,最新的来源获胜——热覆盖冷,新段覆盖旧段。
扫描时从热缓冲的 row_id 集合 + 已提交 tombstone 构建一个 skip set,冷段扫描器拿到 skip set 后,把自己段内的 row_id 追加进去再传给更旧的段。没有多路归并游标、没有跨层序列号协调,一行代码的不变式替代了 LSM 引擎复杂的 merge iterator。
冷数据的读取路径有多快?
冷列式设计真正兑现收益的时刻在查询阶段:
SELECT SUM(x) FROM t(无 WHERE):直接读取每段预计算的统计信息,一行数据都不用扫;SELECT DISTINCT exchange FROM t:从每段字典元数据中提取,不碰行数据;SELECT * FROM t ORDER BY id LIMIT 10:对排好序的各段 row_id 与热缓冲做K 路归并,取够 10 行即停;- 大表扫描:默认开启rayon 并行扫描,多个 Volume 同时处理,小查询则自动走串行路径避免调度开销。
配合 WAL 预写日志与 Manifest 恢复机制,百万行表的冷数据加载从秒级降到毫秒级。完整的持久化与恢复流程见 persistence.md。
崩溃恢复:一次原子状态转换
整套设计的优雅之处在于:manifest 写入是唯一的状态转换点。此前的一切是准备(可丢弃),此后的一切是清理(可重放)。
| 崩溃时机 | 恢复方式 | 数据丢失 |
|---|---|---|
| DML 过程中 | WAL 重放 | 无 |
| checkpoint 中(manifest 写入前) | 旧 manifest + WAL 全量重放 | 无 |
| compaction 中(manifest 写入前) | 旧 Volume 完好无损 | 无 |
| manifest 已写、WAL 未截断 | 冗余 WAL 幂等重放 | 无 |
与主流系统的对比一览
| 概念 | Stoolap 做法 | 相似系统 |
|---|---|---|
| 热缓冲封冻为不可变文件 | Hot Buffer →.vol | RocksDB 的 memtable → SST |
| 列式段 + Zone Map + Bloom Filter | FrozenVolume 格式 | Apache Parquet、Delta Lake |
| Manifest 跟踪段与 tombstone | 每表manifest.bin | Iceberg manifest lists、Delta 事务日志 |
| 最新来源获胜去重 | row_id skip set | Iceberg merge-on-read |
| 有界目标大小的 Compaction | target_volume_rows(默认 100 万行) | LSM 通用压缩 |
| WAL + checkpoint 截断 | seal 后截断 WAL | SQLite、PostgreSQL |
| Delta + 列式 Main 双存储 | 热 MVCC + 冷 Volume | SAP HANA、Apache Kudu |
核心源码与文档入口
想深入源码的读者,可以从这些路径入手(完整模块地图见 storage-engine.md):
- 冷段整体实现:src/storage/volume/
- 封冻逻辑:src/storage/volume/seal.rs
- 段清单与 tombstone:src/storage/volume/manifest.rs
- 带 skip set 的扫描器:src/storage/volume/scanner.rs
- MVCC 引擎(checkpoint / seal / compact):src/storage/mvcc/engine.rs
- 架构总览:docs/_docs/architecture/architecture.md
总结
Stoolap 的存储引擎用三样东西构建了完整的分层:行式热缓冲负责写入与事务隔离,不可变列式冷段负责分析加速,Manifest + 版本化 tombstone负责以最小代价维护一致性。它取 Iceberg 数据湖思想的精华,去掉了 LSM 多层压缩的复杂性,把去重压缩成「最新来源获胜」一条规则——这就是一个嵌入式 SQL 数据库在单机上同时做好 OLTP 与 OLAP 的工程答案。
【免费下载链接】stoolap
A Modern Embedded SQL Database written in Rust
相关推荐
Win11Debloat:一键移除 84 个预装应用与遥测,改动随时可撤销
Win11Debloat:一键移除 84 个预装应用与遥测,改动随时可撤销 Win11Debloat 是一个轻量 PowerShell 脚本,帮 Windows
桌面应用CLITDengine 存储引擎深度解析:行列数据格式、vnode 存储架构与 TSDB LSM 实现
TDengine 存储引擎深度解析:行列数据格式、vnode 存储架构与 TSDB LSM 实现 TDengine 的核心竞争力在于写入与查询性能,其存储引擎针
数据库时序数据库物联网大数据实时分析云原生CubeFS 深度解析:云原生分布式存储的多协议、双引擎与多级缓存架构
CubeFS 深度解析:云原生分布式存储的多协议、双引擎与多级缓存架构 本文以 CubeFS 官方文档《简介》( docs zh/source/overview
存储分布式文件系统对象存储云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考