乐趣区

关于数据库:TDSQL-数据异常的本质和价值详解

数据异样在数据库畛域中较为常见,但目前业界内并没有对于数据异样的通用定义。腾讯金融云 TDSQL 首席架构师李海翔老师携手团队对数据异样的实质和价值进行钻研,该研究成果目前曾经发表在 《软件学报》 上,论文题目为《数据库管理系统中数据异样体系化定义与分类》

该文评审专家认为:本文系统地钻研了数据库的数据异样及其对应的隔离级别,通过形式化的定义,总结和标准了数据异样的类型。基于形式化的解释,解释了不同数据异样之间的本质区别。同时,本文还通过偏序关系对数据异样进行分类,并论述了数据异样与隔离级别之间的关系。另外,本文深刻总结了前人在数据异样畛域的钻研工作,文献空虚。文章具备极高的学术程度,作者分享了其在事务并发管制中数据异样和隔离级别上的粗浅认知,另外作者也提供相应的开源工具用来检测数据异样,是一篇对事务并发管制方向十分有影响力的论文。

本次分享就是基于该篇论文的次要内容,以下是分享实录:

数据异样在数据库中很常见,但数据异样的根本问题,其实并没有失去很好的解决。比方在整个事务处理畛域到底有多少种数据异样?最开始 SQL 规范定义了 4 种数据异样,1995 年 Jim Gray 等人在前者的根底上又提出了 4 种新的数据异样。在浏览了数百篇 Paper 后,咱们也发现从 1995 年到 2017 年之间,一直有人在提出新的数据异样,加起来有将近 20 种。

近几年也陆续有人提出新的数据异样,包含 2019 年 TDSQL 也在分布式系统下报告了新的异样。比方下图中提到的读半已提交数据异样。

在一个分布式系统中,有两个数据项,跨两个物理节点,一个在 A 节点上,一个在 B 节点上。有一个分布式事务,这个分布式事务是一个转账事务,即写 X 和 Y,要给 X 减去 10 元,要给 Y 加 10 元。这时该事务是能够失常执行的。但对于另一个只读事务来说,当它要跨两个物理节点去读数据时,它读到的是数据旧的状态,在另一个节点又读到了新的状态,一个新状态和一个旧状态是在一个事务之前的状态和之后的状态,这两个状态逾越了一个事务的提交的一致性点,呈现账户总额不匹配的状况,产生了数据不一致性景象(统一的状况是 X + Y 或者(X-10)+(Y+10),总和肯定是 X +Y),这就是咱们所说的读半已提交数据异样。

除了上述例子外,还有一些其余的数据异样,例如读偏序、写偏序等。咱们会发现,传统的教科书,在提到数据异样的时候,总是一个一个的说脏读、脏写、写偏序等数据异样别离是什么样子。这些都是针对每一个具体的数据异样,去加以形式化的形容,并没有一个对于数据异样的通用定义(即不能从数据异样整体上给出一个清晰定义)。那到底什么是数据异样?这么多的数据异样之间到底有什么关系?该如何用一个对立的形式或框架来了解所有的数据异样?这些都是没有解决的问题。在事务处理畛域,连“数据异样到底有多少个”这样的根本问题都不晓得,不能答复,可见该畛域还有很大空间。

为了了解数据异样,咱们去摸索了数据异样、变量和并发事务之间的关系。在这个问题的驱动下,咱们把数据异样、变量、并发事务这些相干因素对立在一个模型下,再对数据异样加以形式化的定义,去找出每类数据异样的特色。这时咱们发现数据异样其实有无穷多个。它不只是 SQL 规范所定义的 4 个数据异样,也不只是 1995 年 Jim Gray 等人定义的 8 种数据异样,其实,数据异样有无穷多个。

在数据异样有无穷多个的状况下,咱们要如何去了解数据异样?这就要求必须对数据异样进行分类。咱们用环形式化表白数据异样,对数据异样进行了特色钻研。因为环的边的品种是固定的,能够依据边的品种能够对数据异样进行分类。分好类后,咱们又进一步钻研了非谓词类的数据异样,比方脏读、脏写、不可反复读和幻读这样的谓词类数据异样,看它们之间有什么样的关系。

在了解了数据异样后,咱们又去思考数据异样和一致性之间的关系。目前的事务处理畛域的教科书,对一致性也没有一个对立且残缺的定义。

目前有两种典型的说法:第一种,只提到“不违反完整性因素就叫合乎一致性”。Jim Gray 已经提出,从一个一致性状态变迁到另一个非法的一致性状态,这就叫一致性。但这句话了解起来很形象,存在认知上的艰难。

第二种,源自 Jim Gray 的一篇 Paper,作者们对一致性做过另一种模式的定义。该定义相似隔离级别,把一致性分成几个级别,称为 degree0、degree1、degree2、degree3,并对每一种 degree 用具体规定来进行限定,具体的规定则是屏蔽了肯定的数据异样。换句话说,Jim Gray 其实给出了一个定义,即把一致性和数据异样分割在一起,但他并没有把所有的数据异样和一致性的定义分割在一起(因为事务处理技术的倒退历史上,从没有残缺地定义过所有的数据异样,TDSQL 系统化定义所有数据异样,是该畛域内首个对数据异样体系化定义的工作)。

咱们又进一步去摸索了数据一致性和数据异样之间的关系,再依据之前钻研的后果对一致性下定义。这个定义形容起来很简略,即一致性等于无数据异样。只有没有数据异样那就合乎数据一致性,反之,不统一就等于有数据异样。咱们用数据异样去尝试定义了数据的一致性。

在定义完数据一致性后,咱们又做了一个新的摸索,即钻研数据异样和隔离级别之间的关系。当咱们在数据异样分类的根底上尝试去从新定义隔离级别时,咱们发现隔离级别的定义非常灵活,它能够定义出不同级别或者不同粒度的一致性。

具体地说,咱们基于数据异样这一体系,系统地提出了数据异样实践,再基于这样形象化的定义尝试去定义隔离级别。那怎么去定义隔离级别呢?因为把握了全副数据异样,对数据异样的整体有了清晰认知,定义隔离级别就变为一项灵便的工作,能够是粗粒度的隔离级别的定义,也能够是细粒度的隔离级别的定义。如果很细粒度地去划分,咱们能够分成多个档次,去定义成不同粒度的隔离级别,用以表白不同粒度的隔离级别和数据异样之间的实质差别或实质分割。之所以能这样做,是因为咱们对于隔离级别,有了新的认知:隔离级别是数据异样的一种分类办法。

在灵便定义隔离级别后,对工程零碎而言,就有了很大的帮忙。如果用很简单的隔离级别的定义去实现并发访问控制,其实是比拟难、比较复杂、容易出错且低效率的。因而咱们定义了一个简化的隔离级别。简化级别能够用于工程理论零碎当中,用一些规定就能够屏蔽掉很多数据异样,进而实现较好的性能。另外的一种隔离级别定义形式,较为粗疏,能够用于教学演示,演示数据异样之间的细腻差别,以帮忙咱们充沛认知数据异样。

百尺竿头更进一步。TDSQL 没有止步于系统地定义数据异样,除了把技术扩大到隔离级别外,咱们更进一步地把数据异样体系化工作扩大到了并发拜访控制算法。以死锁为例,死锁是并发编程中常呈现的问题,但死锁的实质是什么?Greenplum 在 2021 Sigmod 上发表了一篇 paper,该文提及了两个分布式死锁的例子。下图中的这种死锁,正是咱们前述发现并定义的一种新的数据异样,称为“Full-write Skew”异样。换句话说,死锁就是一种数据异样。死锁检测算法就是数据异样的环检测算法。这是咱们研究成果价值另一方面的体现。

退出移动版