ITPub博客

首页 > 数据库 > 数据库开发技术 > 并发访问控制(5)--MVCC算法6--MVCC实现实例之一

并发访问控制(5)--MVCC算法6--MVCC实现实例之一

原创 数据库开发技术 作者:那海蓝蓝 时间:2024-05-25 09:00:00 0 删除 编辑

注释:如下所提及的文献,请按照索引号对应参考《分布式数据库原理、架构与实践》一书的引用参考。

PostgreSQL的SSI(基于MVCC)

本节以PostgreSQL为例,讨论文献[68]在PostgreSQL的实现落地示例。注意本节讨论的范围,限制在序列化一词限定的范围内。

PostgreSQL的SSI的理论基础

本节以PostgreSQL为例,讨论文献[68]在PostgreSQL的实现落地示例。注意本节讨论的范围,限制在序列化一词限定的范围内。

首先,PostgreSQL实现SSI,同样也是基于4.4.3节所讲述的理论基础。在文献[68]中,在4.4.3节所讲述的理论基础上,给出一个定理和一个推论,原文如图4-18和4-19:

图4-18 SSI技术的定理图

图4-19 SSI技术的推论图

图4-18所述的定理,说明在一个写偏序发生的有向图环中,必然存在某三个事务T1、T2、T3之间的两条边均是读写依赖构成的,并且,处于最右端被事务T2所指向的事务T3一定是在环中第一个提交的事务。如果这样的情况发生,则写偏序异常出现,意味着违反了序列化。所以回滚三个事务中的一个,则能确保不发生写偏序异常,即确保了序列化。这一点,和4.4.3节所述是一致的。

而读写依赖发生在并发的事务之间,即写偏序发生一定是在并发的事务之间。所以本节所讲述的算法中,对于读、写操作,判断的都是正在执行的事务(如判断条件是“rl.owner is running”,而存在已提交的则回滚当前事务,当前事务则是正在运行的事务),而这些正在执行的事务之间要想形成“依赖”关系,则被依赖的一定应该先提交才能形成正确的结果(即写先进性才能被读操作读到所以才能形成读对写的依赖)。相对于T1而言,T2是写操作所以T2应该先提交,相对于T2而言,T3是写操作所以T3应该先提交,所以三个事务中最右端的T3应该是第一个提交的。

图4-19所述的推论,上面也进行了表述,主要是说,发生读写依赖的事务,一定是并发的事务间,才可能构成读写依赖。

其次,SSI技术,就是基于理论,在并发的、尚在运行的事务之间做检测,检测到图中包括图4-20的情况,则回滚其中的一个事务[1],这样就能阻止环形成。

图4-20 三个并发事务可能构成的潜在冲突图

从并发的角度看,MVCC技术相比S2PL而言可有更大的并发度,所以MVCC称为数据库引擎在事务管理方面的主流技术。而MVCC技术和S2PL技术结合,演变出诸如MySQL的事务处理实现方式,实则是做了一个折衷。但是SSI技术,却是允许更大并发度的一个技术。为什么这么讲呢?

只读事务

PostgreSQL支持只读事务,在一个事务开始的时候,通过“BEGIN TRANSACTION READ ONLY”命令告知事务管理器,这是一个只读事务,不需要修改数据。

对于写偏序,如图4-21的情况发生时,正是有一个事务是只读事务,此只读事务为图4-14中的事务T1。在文献[68]中,有如下定理,对此种情况做了讨论,对SSI技术做了进一步的优化。

图4-21 只读事务定理图

这个定理表明,对于图4-25中的三个事务,如果事务T1是只读的事务,那么事务T3一定是在事务T1获取快照之前就已经提交。

为什么这么说呢?根据第一个定理,如果发生写偏序,那么可以知道事务T3一定是在事务T1之前就已经提交。所以讨论事务T1是只读事务的情况。写偏序发生意味着有环存在,则事务T1之前的事务,假设为事务T0,事务T0指向事务T1的边(T0->T1)不可能是写读依赖和写写依赖,这是因为事务T1是只读的、且不会有写操作。因此事务T0指向事务T1的边只能是写读依赖,所以这意味着事务T0的写操作对于事务T1是可见的(注意现在讨论的是写偏序已经发生后的情况),因此T0一定是T1之前的已经提交的事务。根据之前的推论可知,事务T3应该是环中第一个提交的事务,因此T3应该在T0之前提交,所以T3在T1之前已经提交。一种特殊情况是,事务T3就是事务T0。

这个定理有什么意义呢?这对于SSI技术中对写偏序问题的判断有价值。SSI技术不检测环的存在,而是检测是否存在图4-24的情况,如果是,则挑选其中的一个事务进行回滚,以消除“可能”构成环的可能性。因为有第二个定理,可以对这个判断进行核实,看是否“误判”。

如果检测到图4-20的情况,因为PostgreSQL可以明确知道事务是只读的(另一种特特例是检测是否一直没有发生过写操作),所以继续判断“如果事务T0是只读的,除非事务T3在T1获取快照之前就已经提交”这种情况是可以回滚事务T1或T2(因为T3已经提交)的,否则就不进行回滚操作。这样就限制了回滚带来的“误杀”,提高了SSI技术的识别写偏序情况发生的正确判断率。

Safe Snapshots

在图4-20中,如果处于中间的事务T2不会因存在读写依赖被T1指向,或者不会因存在读写依赖指向T3,即T2不存在,则环也不可能构成。这样,即使T1是只读事务,也不需要检测其是否会构成SSI中的环,即不需要使用SSI中的检测技术。基于此点,论文中提出了“Safe Snapshots”的概念并在PostgreSQL中加以实现。论文中定义的“Safe Snapshots”概念如下:

Safe snapshots: A read-only transaction T has a safe snapshot if no concurrent read/write transaction has committed with a rw-antidependency out to a transaction that committed before T’s snapshot, or has the possibility to do so.

这表明,并发的事务中,如果不存在T2,则只读事务T1就会有一个安全快照(safe snapshot)。所以不能构成环,事务T1就不会被回滚,所以也不需要在只读的事务T1上施加之前提到的“SIREAD”锁,这样就能精准地避免图1-2中描述的写偏序。

但是,实践中却没有办法提前识别出这种情况,即没有办法提前判断一个只读事务是否拥有一个“安全快照”,只有随着并发的事务执行,才能根据事务的执行情况择机判断。PostgreSQL提供了一个并发事务列表,一个只读事务正常加“SIREAD”锁并维护SSI所需要的状态,直到一些事务完成提交,即在一些并发事务完成提交后,这时才能通过宏SxactIsROSafe判断事务T1的快照是否是安全的(判断关键是事务T2的不存在,这样就符合了安全快照的定义),这样就可以提前把事务T1上的“SIREAD”锁去掉,并且让事务T1在可重复读隔离级别下运行(使用SI技术),避免后续继续对事务T1使用SSI的技术做检测。这样能够提高只读事务T1后半段的执行效率。一个特例是,当并发的事务中不存在写事务时,一个只读事务的快照可以被立刻认定是安全的。

Deferrable Transactions

只读事务可以获得安全快照的一个特殊类型,称为“Deferrable Transactions”,其含义是某个只读事务,发起执行后,事务管理器暂不“立刻”执行,而是推迟一会,直到发现没有并发的写事务存在,这时,这个只读事务就可以获取一个安全快照,然后开始执行。这样的事务通过“BEGIN TRANSACTION READ ONLY , DEFERRABLE”告知事务管理器一个只读事务可推迟执行。

延迟只读事务执行,这是因为想获得一个安全快照,而安全快照的好处对于一个只读事务很有意义:

    对于一个长事务,如使用pg_dump逻辑导出大批量的数据的时候,就需要一个安全快照,这样就不能对系统的写操作造成大的性能影响。

再如事务型系统,有时候也需要周期性地执行一些大规模的查询,这时,同理也需要一个安全快照以减少对系统事务型操作的影响。

    推迟只读事务使其在能够获得安全快照时再开始执行,这样做的原因如下:

如果不能获得安全快照,则因需要进行SSI判断而在只读事务上施加“SIREAD”锁,这可能会导致大量的“SIREAD”锁被施加而消耗大量内存,而且一旦施加还不能被及时释放。而获得安全快照则如前所述可以避免施加“SIREAD”锁。

而且,非安全快照的只读事务更容易造成写偏序异常,因而需要参与到SSI技术的检测中耗费CPU。

获得安全快照的事务,也不会面临被回滚的风险。

[1] 挑选T1、T2、T3中的哪个事务做回滚,是一个需要仔细考虑的问题,后续章节会谈及。


需要思考的是:

1 SSI为什么能实现可串行化?

2 SSI是一个好的实现可串行化的技术吗?

再提几个“小”问题我们一起来思考:

1 基于MVCC实现可重复读隔离级别(RR),在理论层面,还遗留有哪些数据异常需要消除?

2 如果RR之后,SSI初衷是消除“Write Skew”,那么可重复读隔离级别到可串行化隔离级别之间、只有“Write Skew”吗?

3 “Write Skew”的定义很简单,为什么SSI实现起来比较复杂?

4 为什么SSI在能消除掉“Write Skew”后,就可称之为实现了“可串行化”?如果这点成立,岂不是在说:可串行化可以具化到 “可串行化==可重复读+去write Skew”?(这个是不是看起来有点怪?)


这些问题,答案在哪里?知数行云在揭晓。


扫码加关注,知数行云,专业有深度


声明:本文禁止用于开发“任何软件程序,包括但不限于训练机器学习或人工智能(AI)系统”。


原文作者:那海蓝蓝知数行云;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-09-02

  • 博文量
    52
  • 访问量
    31017