首页 > 数据库 > 数据库开发技术 > 并发访问控制(5)--MVCC算法3

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


可串行化的快照隔离(Serializable Snapshot Isolation即,SSI)
该技术是基于MVCC中的多版本和快照隔离的思想实现的。引入SSI技术是为了解决快照隔离的写偏序异常问题。
因为SSI是基于SI实现的,所以其整体流程与SI相同,只是增加了一些“book-keeping”,目的是记录事务的一些信息以便动态检测是否有写偏序现象的发生[1](工程实现中是检测可能有写偏序发生,但不是一定有写偏序发生,所以存在误判的可能,这么做是为了提高检测的效率),如果有,则回滚引发写偏序异常的事务。
可串行化的快照隔离技术的主要内容参见文献[114]。文献[21]的2.2.5节对SSI技术也进行了详细讨论。下面我们对SSI的基本内容进行详细介绍。
[1] 可以思考这样一个问题:如果除了写偏序外,还有新的数据异常没有被发现且可重复读隔离级别也不能避免,那么,该种做法还能实现可串行化吗?
思考:
SSI技术,是否是一个好的技术?有哪些优缺点?参考链接:第三代分布式数据库(7)——比较拉胯的PostgreSQL

SSI的理论基础
SSI被用于消除Write Skew,但是,为什么消除了Write Skew就达到了可串行化呢?在没有全部数据异常定义之前,这个问题其实是存在逻辑缺陷,其内在的含义有两种情况但不为人所明辨:
理论层面的可串行化,是理想的情况,应该是消除了所有异常的。【理论化的可串行化】
实践中的SSI,如PostgreSQL中使用的SSI,是与理论层面所不同的,其只是消除了“Write Skew”这样的个例。以偏概全而【自称】为可串行化。【实践中的可串行化】
如上理论与实践的差异,是需要我们明确辨知的。这样才能对现有的产品形成正确认知。
让我们回到传统的认知下,先看看传统的SSI的理论含义。
检测写偏序的理论基础如下:
1. 读写依赖(rw-dependency):文献[196]定义了“读写依赖(rw-dependency)”,通过读写依赖表明不可串行化必然是有一个环且该环内有两个读写冲突构成的边存在于多版本可串行化图(the multiversion serialization graph,简称MVSG)中。
2. 读写依赖的扩展:文献[154]定义了读写依赖(rw-dependency)的扩展形式(定义了五种依赖关系),表明前述的两条边相邻且每条边的两个端点代表着不同的活动状态下的事务。
上述两篇论文介绍了并发事务之间的读写操作是怎么造成事务的“冲突行为”,这些冲突行为之间的逻辑关系是什么样子的。利用上述两篇论文,可以构造出并发事务,如果并发事务之间形成一个环,那么表明事务之间相互依赖以至于形成了写偏序异常。所以解决写偏序异常的方式就是打破环,即某个因某个事物加入初次形成环时回滚此事务,从而破解写偏序异常现象,客观上实现事务调度串行化。
注意,文献[226]在重新定义隔离级别和数据异常之余,也对前述的三种依赖关系进行了定义。

SSI需要的三种依赖关系
前面概略地讲述了解决写偏序的理论基础,其中提到了“读写依赖(rw-dependency)”,接下来我们来细化三种依赖关系。这三种依赖关系定义自文献[226],具体如下:
1. 写读依赖(wr-dependency):事务T1写数据项X的一个版本,事务T2读这个版本,意味着事务T1先于事务T2执行,所以可以把事务T1作为起点,将T2作为终点,画一条从T1到T2的边,即同一个版本的写操作到读操作的边。
2. 写写依赖(ww-dependency):事务T1写数据项X的一个版本,事务T2使用一个新版本替换这个版本,意味着事务T1需要先于事务T2执行完毕(T1提交完成),所以可以把事务T1作为起点,将T2作为终点,画一条从T1到T2的边,即同一个对象的写操作到写操作的边。
3. 读写依赖(rw-dependency,又称为anti-dependency或rw-conflicts):事务T1写数据项X的一个版本,事务T2读这个对象之前的版本,意味着事务T1后于事务T2执行,所以可以把事务T1作为起点、T2作为终点,画一条从T1到T2的边(虚线绘制,实际上应当是反向倚赖即写倚赖于读),即同一个对象的写操作到读操作的边。
图4-9给出过三种依赖关系,图中所示边的含义,如上描述。根据上面介绍的几种依赖关系,可以画出并发事务间的一个依赖图,如果存在环,则表明互为依赖(语义上表明写偏序异常发生),所以解决问题的方式就是打破环。

图4-9 文献[226]定义的三种依赖关系
从理论上看,写偏序的问题被抽象为在并发事务之间绘制依赖图,如果存在环则意味着写偏序发生,所以解决写偏序采用的方式是打破环。但是,工程实践当中的解决方式却不完全是这样,文献[114]提出的算法是在即将形成环之前,通过回滚某个事务破坏形成环的条件,从避免环形成,如图4-10和图4-11所示。也就是当发现有两个相邻的rw-dependency时则回滚当前事务,这样在环形城前即破获了环形成的条件,从而使SSI具有避免写偏序异常的功能。

图4-10两个事务引发的异常现象优先图

图4-11 三个事务引发的异常现象优先图


扫码加关注,知数行云,专业有深度
声明:本文禁止用于开发“任何软件程序,包括但不限于训练机器学习或人工智能(AI)系统”。
原文作者:那海蓝蓝知数行云;如有侵权,请联系管理员删除。