小智 5
摘要:两阶段提交是阻塞的,因此保持两阶段提交的内容尽可能“小”非常重要,以便所有被阻止的操作集最小。CockroachDB 使用带有意图的 MVCC 来实现此目的,仅针对单个意图进行两阶段提交。由于 CockroachDB 提供可序列化事务,因此它会重新排序事务时间戳,以最大限度地减少绝对必要时的阻塞。
\n\n两阶段提交在第一阶段之后会阻塞,而所有参与者都会等待协调者关于是否要提交或中止第二阶段的答复。在此期间,已经发出“是”票的参与者不能单方面撤销他们的投票,但也不能将其视为已提交(因为协调员可能会中止)。因此他们被迫阻止所有需要具体了解该交易状态的后续操作。上面这句话的关键在于“需要”:我们有责任设计我们的系统以将这一设置减少到最低限度。CockroachDB 使用写入意图和[MVCC]来最小化这些依赖性。
\n\n考虑分布式(多键)事务键值存储的 na\xc3\xafve 实现:我希望以事务方式提交一些写入事务t1。t1跨越许多机器上的许多键,但特别值得关注的是它写入k1 = v2. k1在机器上m1(假设k1=v1是之前的值)。
由于t1跨越许多机器上的许多键,因此所有这些键都涉及两阶段提交事务。一旦两阶段事务开始,我们必须注意到我们有写入的意图k1=v2,并且事务的状态未知(事务可能会中止,因为其他写入之一无法继续)。
现在,如果有其他事务t2想要读取 的值k1,我们根本无法给该事务一个权威的答案,直到我们知道两阶段提交的最终结果。t2被阻止。
但是,我们(和 CockroachDB)可以做得更好。我们可以为每个键保留多个版本的值,并有一个并发控制机制来保持所有这些版本的顺序。也就是说,我们可以分配事务时间戳,并使我们的写入看起来(松散地)如下:
\n\n`k1 = v1 committed at time=1`\n`k1 = v2 at time=110 INTENT (pending transaction t1)`\nRun Code Online (Sandbox Code Playgroud)\n\n现在,当t2出现时,它有一个选项:它可以选择在 进行读取time<=109,这不会在 上被阻止t1。当然,有些事务无法做到这一点(如果说,它们也是分布式的,并且有一个不同的组件只需要更高的时间戳)。这些交易将被阻止。但实际上,这可以释放数据库来分配时间戳,以便可以进行多种类型的事务。
正如另一个答案所说,Cockroach Labs在这里发表了一篇关于 CockroachDB 使用 MVCC 的文章,其中还解释了一些进一步的细节。
\n| 归档时间: |
|
| 查看次数: |
781 次 |
| 最近记录: |