关于 mvcc
mvcc 是介绍 Turso 多版本并发控制实现的实验性指南,面向开发或测试 MVCC 特定行为的开发者,说明配置、行版本、架构、检查点及当前限制。
主要功能
- 01运行时 MVCC 配置
- 02行级版本与快照
- 03MVCC 存储架构
- 04检查点流程
- 05已知实现限制
- 06MVCC 专项测试命令
适用场景
- 01为数据库启用 MVCC
- 02调查快照隔离行为
- 03测试 MVCC 变更
- 04评估恢复与内存限制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tursodatabase/ turso --skill mvcc安装后在 Claude Code 中输入/mvcc确认已加载。
详细介绍
MVCC 指南(实验性)
多版本并发控制。仍在开发中,尚未达到生产就绪状态。
重要:调试时请忽略 MVCC,除非问题特定于 MVCC。
启用 MVCC
PRAGMA journal_mode = 'mvcc';
这是运行时配置,不是编译时功能标志。按数据库单独设置。
工作原理
标准 WAL:每个页面只有一个版本,读取方看到读取标记时的快照。
MVCC:有多个行版本,采用快照隔离。每个事务在开始时获取一致的快照。
与 WAL 的主要区别
| 方面 | WAL | MVCC |
|---|---|---|
| 写入粒度 | 每次提交都会写入完整页面 | 仅写入受影响的行 |
| 读取方/写入方 | 彼此不会阻塞 | 彼此不会阻塞 |
| 持久化 | .db-wal | .db-log(逻辑日志) |
| 隔离级别 | 快照(页面级) | 快照(行级) |
版本管理
每个行版本都会跟踪:
begin- 开始可见的时间戳end- 删除/替换时的时间戳btree_resident- 启用 MVCC 之前是否已存在
架构
Database
└─ mv_store: MvStore
├─ rows: SkipMap<RowID, Vec<RowVersion>>
├─ txs: SkipMap<TxID, Transaction>
├─ Storage (.db-log file)
└─ CheckpointStateMachine
每个连接独有:mv_tx 跟踪当前的 MVCC 事务。
共享:包含无锁 crossbeam_skiplist 结构的 MvStore。
关键文件
core/mvcc/mod.rs- 模块概述core/mvcc/database/mod.rs- 主要实现(约 3000 行)core/mvcc/cursor.rs- 合并 MVCC 与 B-tree 的游标core/mvcc/persistent_storage/logical_log.rs- 磁盘格式core/mvcc/database/checkpoint_state_machine.rs- 检查点逻辑
检查点
定期将行版本刷新到 B-tree。
PRAGMA mvcc_checkpoint_threshold = <pages>;
流程:获取锁 → 开始 pager 事务 → 写入行 → 提交 → 截断日志 → fsync → 释放锁。
当前限制
尚未实现:
- 垃圾回收(旧版本会不断累积)
- 重启后从逻辑日志恢复
已知问题:
- 检查点会阻塞其他事务,甚至包括读取操作!
- 无法将数据溢写到磁盘;内存使用方面存在隐忧
测试
# Run MVCC-specific tests
cargo test mvcc
# TCL tests with MVCC
make test-mvcc
使用 #[turso_macros::test(mvcc)] 属性启用 MVCC 测试。
#[turso_macros::test(mvcc)]
fn test_something() {
// runs with MVCC enabled
}
参考资料
core/mvcc/mod.rs记录了数据异常(脏读、丢失更新等)- 快照隔离与可串行化:MVCC 提供前者,而非后者
评论
支持 Markdown