NuoDB
by NuoDB

MVCC.第2部分:漂亮的照片和一些例子

问候Stalwart技术乌努恩人!我回到了我之前的MVCC帖子。 Part 1 给出了一个高水平的摘要概述了MVCC旨在解决的问题,以及数据库如何使用MVCC来最大化并发性的基本剪影。现在,在第2部分,我希望通过给出具体的例子来使这些概念更具体。

示例1:读取和更新

考虑其中至少有3行的表。假设每行都有一些id值。鉴于此,让我们检查一个事务正在读取整个表的情况,而另一个事务正在同时更新行(同时意味着两个事务同时都处于活动状态和处理,因此它们的效果无法向历史中抽象地订购它们)。
读+更新

 

事务1开始“在”事务2之前“开始,并开始读取它可以找到的表中的每个条目。同时,交易2启动并追捕可更新的记录。事务2延时事务1以记录100,早期滑动并更新它。因为事务2仍处于活动状态,所以更新正在挂起(直到提交,它不可见其他事务)。在基于锁的系统中,事务1可能必须将表格锁定为整体或验证,而在读取它时不会更改。但是通过MVCC,当交易1最终访问记录100时,它只需读取最新的承诺版本(这是1)。 h没有作者阻止了读者,没有读者阻止了作者。没有人必须阻止或回滚。

示例2:多重非重叠更新

请考虑与示例1中的相同表格。但是,在这种情况下,两个单独的事务将尝试更新表中的行。

更新+更新

 

交易1和2同时启动。事务1想要更新记录142,事务2想要更新记录100.这两个事件都遇到了一个完全承诺的版本,因为最新,因此他们可以立即更新它们。不需要阻止,并且两个事务都可以以任何顺序进行,或者任何顺序或组合都失败,并且它们不必彼此协调。

示例3:更新冲突

将与示例1的相同表1。在此示例中,两个事务将尝试更新相同的记录。冲突可能是不可避免的,这只是一个问题,当您检测到它以及您如何处理它时,您如何检测到它。

更新冲突

 

事务1和2同时处于活动状态,两者都在尝试更新记录100.假设事务2获取竞争并将新版本的记录100赢得其所请求的值。该版本是“挂起”或“锁定”,这意味着事务1将看到它在击中记录100时丢失了比赛。此时,事务的行为取决于用户请求的隔离状态数据库中的并发控制器。如果用户请求某些读一致性,则并发控制器有两种选择:它可以立即失败T1,让用户决定如何继续(可能是通过重试)进行操作。另一种选择是“暂停”T1,直到已知T2的最终状态。您可能想要这样做的原因是T2可能在后来失败的其他原因。如果发生这种情况,则记录100的版本3基本上是“坏”,可以通过T1(和其他人)忽略,然后T1可以再次启动并更新记录100.但是,如果T2不会失败,则T1将等待一点,无论如何都会失败。这两个选项都有优点,两者之间的选择是一种依赖于应用程序的特征的工程权衡。 Nuodb允许用户选择他们想要的行为。早期失败是“一致读取”模式(Nuodb-ESE for Snapshot隔离)的行为,但是对于阻塞行为,用户可以在“写入提交”或“读取的承诺”模式下运行,这将确保高度争辩的数据不会导致大量的交易失败。对于更精细的控制,用户可以使用“一致性读取”模式下使用“选择for Update”语句,切换到由事务操作的数据的子集的阻塞行为。

下图说明了T1等待T2的情况,而T2稍后会发生故障:

更新冲突+回滚

 

T2失败,然后系统负责回滚其变化。请注意,所有回滚文件都可以与其他事务的前进操作同时发生。这是NOODB的一个重要特征,因为它意味着交易回滚不需要以其他方式在世界“重置”时以任何方式阻止或暂停。任何表演修改就地交易系统必须具有高度并发的撤消机制,否则每当事务失败时,一切都会触摸尖叫。

NB: 写入锁定记录版本是急切故障检测的示例。使用这样的系统的并发控制器将能够在发生时检测事务干扰。另一个选项将是延迟故障检测,其中交易双重检查其在提交时的初始状态,并且仅在事实之后检测到冲突。 SQL的语义肯定会使急切失败检测优选(SQL语句不能返回,直到它们的效果成功,即它们具有同步行为)。通常,写冲突的渴望检测方案往往会更好地执行。

看一眼 Part 1, Part 3, 和 Part 4 在这个MVCC系列中,以及我们的两部分系列 MVCC.中的隔离级别:第1部分 & Part 2.