MVCC是确保事务隔离的一种方法

哈Ha 我叫弗拉迪斯拉夫·罗丹(Vladislav Rodin)。目前,我是OTUS高负载架构师课程的负责人,并且还教授软件架构课程。

尤其是对于新课程“高负荷建筑师”的开始,我写了一些材料,很高兴与大家分享。



介绍


上一次,我们与您讨论了削弱数据库中事务隔离的后果。今天,我们将更详细地讨论确保隔离和避免所考虑的异常的一种方法。您可能已经注意到,在上一篇文章中,经常区分两种方法:一种是基于记录具有某些版本的事实,第二种是基于我们将以一种或另一种方式阻止记录的事实因此,区分了两类数据库:版本化数据库和阻止程序今天,我们将讨论什么是版本控制器,让我们下次再考虑阻止程序。

版主


正如我所说,方法之一是基于版本控制。也称为乐观方法或MVCC(多版本并发控制)实际上,会发生活动交易的版本存储。

版本存储在哪里?


该机制的实现取决于数据库。我将举一些例子。

PostgreSQL的


每个交易都有一些id-shnik的特征。 id-shnik交易单调增长。任何行都有2个属性,这些属性表示用于提供该机制的元信息:Updated_by_id-上次更新该记录的事务的ID,delete_by_id-删除该记录的事务的ID。当新的事务到达时,数据库确定当前正在执行的事务的ID缺口,这些事务所做的更改将在传入事务中被忽略。事实证明,传入事务就像使用其数据版本一样工作。旧版本的数据与当前版本存储在同一位置。如果更新到达,则添加另一行,并且该记录变为活动状态。同样清楚的是,为了使此方案正确运行,需要“垃圾收集器”:如果某些记录的delete_by_id = 100,并且当前事务中的最小id-shnik为150,则必须删除该记录。

MySQL(InnoDB引擎)


只有当前版本存储在MySQL数据库中。当更新到达时,表文件中的数据被更正。调整数据后,先前版本位于回滚日志中。MySQL中有多个回滚日志(insert'ov和update'ov有所不同)。如果事务需要该行的先前版本,则系统转到撤消日志并还原必要的版本。版本也由交易ID决定。

甲骨文


该方案类似于MySQL:当前版本存储在数据文件中,而旧版本则通过撤消日志得以恢复。Oracle中的撤消日志被周期性地重写。因此,当事务需要非常旧的记录版本,但是在撤消日志中不再存在该记录时,可能会出现这种情况。如果发生这种情况,则事务将失败。

MS SQL


MS SQL允许同时包含版本控制程序模式和阻止程序模式。要在数据库设置中启用版本控制模式,必须启用快照。在MS SQL中,有一个系统表(tempdb),用于存储临时表。 tempdb用于存储旧版本,而表包含当前版本。系统进程监视tempdb中是否存在没有人引用的版本,可以删除它们。如果交易是长期的,则将为其保存版本。 Tempdb增长,达到其最大大小,MS SQL分配了一点磁盘空间。如果结束,则无法执行具有快照隔离的事务。如果使用这种操作模式,则有必要监视多头交易,因为及时回滚这样的事务可能会花费尽可能多的费用,甚至更多。

矛盾冲突


这种方法称为乐观方法,因为我们希望如果执行并行数据更改事务,不会有冲突。发生冲突时会怎样?假设事务T1更改10,000条记录,而事务T2并行更改1条记录。如果碰巧在这10,000条记录中包含了这1条记录,则将回滚其中一个事务:如果首先执行T1,则将回滚T2,否则将回滚。

回滚机制


版本化版本中的事务回滚机制取决于实现。例如,在PostgreSQL中,一个事务被标记为疏散,并且真空释放磁盘空间。这样的机制足够快。在Oracle中,为了进行回滚,将从撤消日志中还原数据。在这种情况下,操作时间会增加,但是仍然比储物柜快得多。MySQL与Oracle的工作方式相同。

结论


乐观的方法是好的,因为写者不会阻塞读者,而读者只是阅读他的数据版本。因此,如果主要负担是读书而不是写作(博客,报告以及您需要经常大量阅读的其他情况),那么版本控制是有益的。



在此处了解有关该课程的更多信息。



All Articles