4

我目前正在阅读 dbms 书,据我了解,Mvcc(多版本并发控制)用于高并发读写事务。但是“搜索结构的并发控制”一章提到了 B 树的不同锁定概念(锁定耦合、链接技术等)。

Mvcc 不是应用在 dbms 中 B-Tree 的内部和叶子节点上吗?B-Tree 并发和 MVCC 完全不同吗?如果是这样,Mvvc 是如何在 dbms 中实现的?

4

2 回答 2

3

MVCC 可以通过多种方式实现。唯一的要求是可以使用某种较旧的行版本。

例如,SQL Server 将它们存储在一个临时数据库中,该数据库在服务器重新启动时会重置。

Postgres 将行版本作为隐藏行直接存储在 b 树中。它将隐藏的键列添加到树中。当从树中读取时,只公开逻辑上应该看到的版本。

RavenDB 的 Voron 将 b-tree 页面作为不可变数据进行管理。写入会创建全新的树。因此,MVCC 被实现为从正确的不可变树中读取。

数据库很少长时间锁定物理结构。让数据库客户端停止数据库内部结构的进展并不是一个好主意。内部结构通常被非常短暂地锁定。逻辑行锁是分开处理的。

如果我不得不猜测concurrency control on search structures是指物理线程安全。这通常不涉及 MVCC,因为不需要管理多个版本。普通的内存锁足以进行短暂的访问。

于 2016-07-30T20:40:27.587 回答
1

MVCC 意味着您不需要使用锁。

想象一下,每笔交易都有一个数字时间戳,每笔交易都会增加一个数字时间戳。在此示例中,我们有事务 1 和 2。

事务 1 读取 A 并写入值 (A + 1)。快照隔离创建事务 1 拥有的 (A) 的临时版本。A 的读取时间戳设置为事务 1。

如果事务 2 同时出现并读取 A,它也会读取已提交的 A——它不会看到 A + 1,因为它尚未提交。事务 2 可以看到 == lastCommittedA 和 <= 事务 2 的 A 版本。

在事务 2 读取 A 时,它还会检查 A 的读取时间戳,并查看事务 1 是否存在,并检查事务 1 时间戳 < 事务 2 时间戳。因为 1 < 2 那么事务 2 将被中止,因为它已经依赖于 A 的旧值。

(我已经在 J​​ava 中实现了 MVCC。请参阅事务运行器和mvcc代码我已经在 Python 中实现了 btree。)

于 2021-06-22T18:08:18.237 回答