name: mvcc description: 实验性MVCC功能概述 - 快照隔离、版本控制、限制
MVCC指南(实验性)
多版本并发控制。正在进行中,不适用于生产环境。
关键:在调试时忽略MVCC,除非bug是MVCC特定的。
启用MVCC
PRAGMA journal_mode = 'experimental_mvcc';
运行时配置,不是编译时功能标志。每个数据库设置。
工作原理
标准WAL:每个页面单一版本,读取者在读取标记时间看到快照。
MVCC:多行版本,快照隔离。每个事务在开始时间看到一致的快照。
与WAL的关键差异
| 方面 | WAL | MVCC |
|---|---|---|
| 写入粒度 | 每次提交写入完整页面 | 仅受影响的列 |
| 读取者/写入者 | 不互相阻塞 | 不互相阻塞 |
| 持久性 | .db-wal |
.db-log(逻辑日志) |
| 隔离 | 快照(页面级别) | 快照(行级别) |
版本控制
每个行版本跟踪:
begin- 可见时间的时间戳end- 删除/替换时间的时间戳btree_resident- 在MVCC启用前已存在
架构
数据库
└─ mv_store: MvStore
├─ rows: SkipMap<RowID, Vec<RowVersion>>
├─ txs: SkipMap<TxID, Transaction>
├─ 存储 (.db-log文件)
└─ 检查点状态机
每连接:mv_tx 跟踪当前MVCC事务。
共享:MvStore 使用无锁 crossbeam_skiplist 结构。
关键文件
core/mvcc/mod.rs- 模块概述core/mvcc/database/mod.rs- 主要实现(约3000行)core/mvcc/cursor.rs- 合并MVCC + B树游标core/mvcc/persistent_storage/logical_log.rs- 磁盘格式core/mvcc/database/checkpoint_state_machine.rs- 检查点逻辑
检查点
定期将行版本刷新到B树。
PRAGMA mvcc_checkpoint_threshold = <pages>;
过程:获取锁 → 开始分页事务 → 写入行 → 提交 → 截断日志 → 同步 → 释放。
当前限制
未实现:
- 垃圾收集(旧版本累积)
- 重启时从逻辑日志恢复
已知问题:
- 检查点阻塞其他事务,即使是读取!
- 无磁盘溢出;内存使用担忧
测试
# 运行MVCC特定测试
cargo test mvcc
# 使用MVCC的TCL测试
make test-mvcc
使用 #[turso_macros::test(mvcc)] 属性进行MVCC启用的测试。
#[turso_macros::test(mvcc)]
fn test_something() {
// 启用MVCC运行
}
参考文献
core/mvcc/mod.rs记录数据异常(脏读、丢失更新等)- 快照隔离 vs 可序列化:MVCC提供前者,非后者