小故事:这幅图为什么叫做“一致性八仙图”?
一致性八仙图
所谓八仙过海各显神通。这是该图特点之一。
长期以来,数据库界期待能有一套理论或工具,对数据库的一致性进行测试和验证,以掌握目标数据库对于一致性的实现程度。这个需求,非常迫切。
任何一个数据库系统,都缺乏系统性的一致性校验的方法和工具,致使任何数据库系统都没有依据去讲自己的一致性满足程度是什么样子的。
Oracle虽能设置可串行化隔离级别,可在时间的长河中未经得起考验而被后人发现其可串行化只是相当于SI的隔离能力,成为一个大家未笑(无奈而不能笑)、未重视(忍受而渐渐漠视麻木,没有更好而只能忍受)的笑话。
当自家出具的东西,自己不可解释、自己不能正确实现的时候,这个背后的因素,究竟是什么?
著名的Jespen工具问世,似乎拯救了一大批数据库系统,很多数据库系统使用其做一致性测试,使得缺乏一致性验证方法和工具的情况有所改善。
但亦如下所述,Jespen也有诸多不足(参考“第三代分布式数据库(1)——踢球时代”之表1),不能够很好地评测数据库的一致性。
“一致性八仙图”,却能够完美地评测各种数据库,使得各种数据库的一致性能被清晰地展现在大众眼前,数据库八仙在前,“尽显”一致性神通(对比着看,会更有帮助哦)。
该图给出了如下信息:
1. 评测任何数据库系统(SQL接口或API接口的)的一致性实现能力。
图中给出11个数据库16个版本的一致性的评测结果,包括主流数据库如Oracle、PostgreSQL、MySQL等。实践中,测试了更多的数据库系统,如国产Pg系列的、MySQL系列的等,评测结果同其母版,故不罗列。
2. 评测每一个隔离级别下数据一致性的正确性实现能力和细节。被测试的每个数据库的所有隔离级别的实现细节和差异一览无余。
3. 评测系统,适用于事务型的单机数据库系统、分布式数据库系统。只要是提供事务处理能力的,都可被测试,连Greenplum、MongoDB这些也可被测试哈。
4. Cell单元格含义:
a) 黄色背景的A:出现数据不一致性
b) 绿色背景P:无数据不一致性(不一致性现象被避免)
c) 蓝色背景R:无数据不一致性(不一致性现象被按一定规则回滚)
d) 红色背景D:无数据不一致性(不一致性现象被死锁检测方法回滚)
e) RU,读未提交;RC,读已提交;RR,可重复读;SI,快照隔离;SER,可串行化
第一,从隔离级别级别的角度看:
1. 首先,RU隔离级别下,MySQL和SQL Server“黄色背景A”最多,表明RC隔离级别下,这两个数据库的数据正确性存在较多问题,但这点没什么影响,因为应用开发通常都设置为RC隔离级别。部分数据库如PostgreSQL虽然提供了RU级别的设置,但其实际效果等同于RC,“黄色背景A”不是很多,基本上符合ANSI-SQL的定义(但ANSI-SQL只定义了四种数据异常)。
2. 其次,RC隔离级别中,SQL Server的“黄色背景A”最多,表明RC隔离级别下,这两个数据库的数据正确性存在较多问题;而Oracle、PostgreSQL、MySQL、TiDB、OceanBase在RC下相近,但都有较多的数据异常不能消除,这些不能被消除的数据异常,远多于ANSI-SQL标准所对应的RC级别下只能消除的Dirty Write、Dirty Read这两个。
3. 再次,在RR隔离级别级别中,PostgreSQL的“黄色背景A”少于MySQL、TiDB、OceanBase等,说明PostgreSQL在该级别下一致性做得最好,其次较优的是MySQL。而SQL Server的RR和SER却是有着相同的结果,消除了所有的数据异常。
4. 第四,对于提供了SI隔离级别的SQL Server和MongoDB(图中用SI表示),和对于提供了乐观锁实现类似SI隔离级别的TiDB(图中用Opt表示采用乐观锁)相比,他们有着相同的一致性能力。
5. 第五,不能完全保证数据一致的,即不提供SER级别的的数据库如MongoDB、OceanBase(MySQL兼容版本)、TiDB等数据库的数据一致性能力止步于此,可以看到在RR级别下还有较多的“黄色背景A”。
6. 第六,名义上提供SER的如Oracle、Greenplum、OceanBase(Oracle兼容版本),SER下存在若干种数据不一致的问题。
7. 第七,在SER即可串行化隔离级别下(除了不支持SER的外),SQL Server、CockroachDB、PostgreSQL、MySQL、TDSQL、MyRocks能完全确保数据的一致性;但是从一致性八仙图中我们可以观察到,这些数据库为了确保SER,采用的方法是不同的,有的是“蓝色背景R”如PostgreSQL采用的SSI算法回滚某些数据异常(Write Skew等),有的是“红色背景D”如SQL Server 和MySQL采用死锁检测的方式回滚Write Skew等。——这是一个有趣的现象,背后有着深刻的“洞察”,后续单独成文。
8. 事实上,ANSI-SQL标准定义的隔离级别,是一个鸡肋。
第二,从同一个数据库的角度看:
1. MongoDB和CockroachDB 提供单一的隔离级别,尤其是CockroachDB作为一个分布式数据库,只提供可串行化隔离级别(其早期版本还提供SI隔离级别,但在后续的版本中被去掉了)。这是以一个非常正确的选择,其技术路线的确定者必定深刻理解了分布式数据库和分布式事务的实质,这点值得其他任何数据库学习,分布式数据库没有必要提供弱隔离级别。一个分布式数据库如果想在事务处理领域站稳脚跟,选择学习CockroachDB的设计方式,是最佳选择。——这也是一个有趣的现象,背后的“洞察”亦非常深刻,后续单独成文讨论。
2. PostgreSQL基于SSI算法实现了可串行化隔离级别,消除了一致性八仙图中的Write Skew、Write Skew Committed和Step IAT三类数据异常(请注意,SSI消除的不仅仅是Write Skew)。但是,SSI算法对于PostgreSQL而言,却是多余的;PostgreSQL为实现可串行化化花费了巨大的力气却做了多余的无用功,非常可惜,这是数据库引擎研发人员的认知错误造成的,有效地展现了传统的事务知识认知的局限性。——这也是一个有趣的现象,背后的“洞察”亦非常深刻,后续单独成文讨论。
3. Greenplum的名义SER与PostgreSQL的RR级别能力相当,但是Greenplum作为一个分布式数据库,其处理分布式一致性时的方法与单机的PostgreSQL是有所不同的。Greenplum处理分布式一致性时采用的方法,相当笨拙,也相当低效,有着巨大的改进空间。——这也是一个有趣的话题,背后的“原理”非经典教科书可见,后续单独成文讨论。
4. OceanBase(Oracle兼容版本)只是名义上提供了SER,类似Greenplum,其SER与其RR级别能力相当。OB的早期版本通过超时机制解决分布式死锁问题,2023年在ICDE发表了分布式死锁解决算法,但该算法也局限在传统的死锁解决算法中,因此有着传统的死锁解决算法的低效问题存在。这点其实和Greenplum很相似。——如何解决分布式数据库的死锁问题,是一个有趣且重要的核心的话题,背后的“原理”亦非经典教科书可见,后续单独成文讨论。
5. 相比如上的几个数据库产品,TiDB的一致性能力,整体上较弱。其Opt方式的一致性能力,优于其RR级别。但该数据库产品也存在着分布式死锁解决方法低效的问题。
6. SQL Server 和MySQL的一致性能力都较强,其解决数据异常的方式也相似。对比他们对于SER和RR的结果,我们会发现,其对于同一个数据异常如“Read Skew”、“Lost Update”和“Write-read Skew”等,两种隔离级别对同一个异常的的处理方式却不同,这其实违背了“隔离级别逐层递进实现”的原则,表明其事务处理技术的实现,处于混乱状态,没有能统一规划而被实现。而且,它们确保一致性的细节能力,却弱于PostgreSQL。——MySQL在一致性实现能力方面弱的原因,涉及细节众多,期待后续单独成文讨论。一致性八仙图背后的理论能够洞察数据库的并发实现细节,并准确衡量并发代码层的优劣。
7. 国产数据库中,TDSQL在一致性方面的能力最强,且作为一个分布式产品,其一致性能力之强是较为少见的。TDSQL在金融行业的应用范围是最广(国内Top10银行TDSQL已占6成)的,其一致性等核心技术对商业起到了重要的支撑作用。但可惜的是,其实现算法同样存在效率差的问题。
8. 基于PostgreSQL的一些其他品牌产品其一致性能力基本等同PostgreSQL,基于MySQL的一些其他品牌产品其一致性能力基本等同MySQL。
第三,从用户的角度看:
1. 金融电信证券等行业,对数据一致性的要求最高,期待数据库没有任何数据异常,该要求是对事务型数据库系统选型的核心标准之一。所以,一个数据库的一致性能力,决定了其数据的正确性能力,也影响着其是否能进入金融等行业的核心业务。用户期望有一个客观的一致性评测标准,能精准的验证目标数据库的一致性能力。这个期盼,自事务处理技术诞生之日起至今,已经过了花甲之年。漫漫历史长河中短暂的人生,一粒尘沙,又有几个花甲之年可等待?
2. 各个数据库厂商,同样期盼,在数据库版本发行前,能很好地测试验证其发行版本的一致性能力,但可惜,一直没有好的方法。于是,数据库厂商只能依靠长年累月积累下的各种测试用例和bug集作为回归测试用例集,来验证“新版本不再有已经被发现过的一致性错误”,对于未来是否会被发现新的一致性bug,心里没底。
3. 数据库研究者,也一直期望,能有一套方法论,能够在理论层面,全面说明一致性的验证方法。但自从有了“可串行化理论”,自从“可串行化理论”被奉为为黄金圣律后,一部分早期的研究者便认为一致性的实现已经有了理论保证则不必再费心血研究什么是不一致等事情了,于是……。但是,研究者们却未深入思考:一致性又何从验证呢?可串行化理论为什么不能验证数据库的一致性呢?“确保一致性的方法”和“验证一致性的方法”之间,会有什么关系吗?——这是一个非常重要也很有趣的话题,值得深入思考,后续单独成文讨论。一个理论如果完备,是不是应该既能保证正确性,又能验证正确性?
4. 有了一致性八仙图,从此数据库的一致性能力,有了验证了评测的方法和工具,各个数据库的一致性能力,相信能有大的改进与突破。
业界,有一个普遍被认可的观点:一个新的数据库产品,至少需要10+年才能成熟可用?
那么:
Q1:为什么一个新的数据库产品,其研发、打磨、推广周期需要10+年?
Q2:如何能加速这个过程?
A:这两个问题,可从多个角度思考。我们单独从数据正确性的角度来分析,因为这是数据库最基本的核心问题:
1. 事务型数据库的核心目标有2个:在并发操作下,一是保证数据正确性、二是尽可能高性能。
2. 为确保核心目标,需要一套理论来论证目标的可行性,这就是传统的可串行化理论,可是该理论有2点缺失:
2.1依据可串行化和冲突可串行化,理论层面尚不能保证数据100%正确。这意味着理论层面有缺失。--重要问题,单独成文讨论。或许很多人会说:你竟疯了不成,敢如此大胆、对金科玉律胡言乱语!嚓~嚓~嚓
2.2 完备的理论,至少具备2点:正确性和验证方法。一个完备的理论应该既能够提供正确的解释和预测,又能够给出方法验证其正确性。这两个方面的考量是评估一个理论是否完备的重要标准。可串行化理论,缺乏对依据其研发的数据库产品的一致性验证方法,这是该理论的缺失之处,也是不完备之一(还有不完备之处)。
2.3 因此,在理论缺失的情况下,数据库产品的正确性不能被很好地验证,该产品何以有理由被推向市场?
3. 但是,Oracle等厂商就是把不成熟的产品推向了市场,其采取了三种方式:
3.1 定义隔离级别:1992年ANSI-SQL标准把该问题“标准化”,似乎该问题在隔离级别的背景下成为了“天经地义”之事!标准如此,何人可质疑之?芸芸之口,堵之!众生之脑,塞之!--隔离级别是可以灵活定义的,不应被限制在ANSI-SQL标准内(参考文献 [1] ),可不同于ANSI-SQL标准
3.2 把球踢给用户,发明了“SELECT…FOR UPDATE”的方式,让用户自己为数据的一致性负责。(文后附了一个小故事,可以从时间脉络,看出Oracle在此方面的“贡献”)
3.3 既然把球踢给了用户,那么意味着有了海量的测试场景可验证数据的正确性,一旦发现问题,作为bug修复即可。这也是在理论层面没有办法的背景下,实践中可选的一种方式。据说,Jim Gray提出的Write Skew和Read Skew等就是在实践中被用户发现数据出现了不一致而经过大量分析论证才被提出的。因此,把用户作为小白鼠,使得各个数据库产品以10+的周期长期积累bug(使得厂商的回归测试用例逐渐完善),一致性问题才逐步趋于稳定,实践中被报告的数据异常才越来越少,这使得数据库产品的可用性增强。但是,也使得一个数据库产品成熟周期变得无比得长,10+年、20+年…。理论和实践都不行,用户不得不忍受之,产品不得不依靠时间来打磨。
3.4 但是,从20世纪90年代到现在的30+年中,新的数据异常还是被不断报告出来,意味着数据的正确性依然有多种风险(应用日益丰富,使得数据正确性的风险暴露的可能性增加),意味着数据库正确性无论是在理论还是在产品实践方面,不得不做彻底地改进了。具体情况可参考文献[1]。
Q3:那么,数据库一致性的保证,是否能够加速,如把一个产品成熟周期,压缩到2年甚至1个年?如果能,如何加速?
A:我们大家能感受到一个趋势,最近的若干年内,各种新数据库产品越来越多,对不?
新应用大幅增多对数据库提出丰富的新需求,老数据库产品演进包袱太重而进化困难,这些新情况使得新的数据库越来越多百花齐放。
可是尽管新产品增多,但是它们依然面临难以进入核心应用的窘境。从技术层面看,这是为何?
而只要提供“艰难繁复”的事务处理技术,新的数据库产品,都将面临着着如何快速成熟稳定、如何加速推向市场的问题。--这是时代的需求!
一个数据库产品,无论新旧,如果不能从理论和实践两个方面为用户彻底解决最基础的一致性问题,即使该产品被用到了若干环境中,但终究难以让用户100%心安。
顺应时代之需,一致性八仙图和其背后的技术问世——该技术从理论和实践两个层面加以着手。
首先,数据异常现象可被统一建模,包括所有已知和未知的数据异常,从理论层面首先解决数据正确性问题。
其次,一致性八仙图,可全面验证数据库数据的正确性。这使得理论层面具备了最基本的2个特征(一个完备的理论应该既能够提供正确的解释和预测,又能够给出方法验证其正确性)。
第三,一致性八仙图背后的一致性评测技术,可加速数据库数据正确性的验证(分钟级),即加速数据库产品的成熟稳定,大幅缩短一个产品推出的周期。
未来,经历过一致性八仙图的评测认证的数据库产品,将会在公众中树立起良好的数据正确性形象,获得大众的信任。在实践中加速产品走向核心应用也将指日可待。
在数据库界,多年以来,无论传统数据库技术大厂还是开源数据库还是新研发的NewSQL数据库,都不能体系化地建立一致性回归验证系统。【这个听起来,似乎是一个非常令人匪夷所思的事情,居然数据库厂商们也做不了这样的工作,他们只能零星地构造个别测试用例,放到回归用例集中验证一致性;而完整地测试、评价每一个版本的数据库系统的一致性,却没有任何好的办法】
之后,业界诞生了一个很知名的系统,就是大名鼎鼎的Jepsen/Elle[2]。该系统是迄今为止最好的数据库一致性验证工具。这里,我们不对Jepsen/Elle的特性展开介绍,而是讨论一下Jepsen/Elle的不足。
Jepsen/Elle之所以有价值,是因为其原理基于冲突图,其采用了Adya的论文(参考文献《Generalized isolation level definitions》)。Jepsen/Elle在构建一致性测试用例的时候,是基于冲突图进行的。Adya在如上参考文献中把脏读和中间读异常作为特例未纳入其定义的冲突可串行化体系,故Jepsen/Elle对脏读和中间读异常的测试也是作为特例加以构造。
在冲突图中,一个有向环图中,其顶点和边的个数,是可多可少的,即环的样子是无穷多个,这导致Jepsen/Elle在理论上需要构造无穷多个环,才有希望能把大部分环测试到。一旦使用Jepsen/Elle测试,如果想测试到所有的环,则只能用无穷多的时间来运行该工具。显然,在资源有限和时间有限的情况下,我们是不会有机会无休止地运行该工具进行测试的。因此对于一个目标数据库进行测试的时候,每一次测试都是“不完备”的,这是Jepsen/Elle最致命的问题。测试不完备,意味着测试只能靠“运气”,正确性无法完全得到保证。
另外,什么情况下能够构成“冲突环图”?用几个或几十个乃至几十万个并发事务,就一定能精确的构造出环吗?如果不知道环的组成规律,何以每次测试都能构造出足够多的环来验证正确性、并且提高其验证、测试的效率呢?冲突图的理论,不能在这个层面对Jepsen/Elle提供理论支持,因此Jepsen/Elle构造测试用例有个特点:随机。随机的构造测试用例,使得其验证一致性的目的性和效率大幅度降低,同时使得每次测试,都不能容易“复现”之前发现的问题(不能复现问题是构造测试用例的禁忌之一)。
因此采用该工具进行验证,其实既不可信也不可用(没有更好工具的时候,只能退而求其次了)。
有些有Jepsen/Elle实践经验的同学,未必同意该结论,因为在实际的使用中,有时候确实能凭借该工具发现一些问题(即不一致的bug)。可是,分析其原理我们可知,代表了业界最高水平的Jepsen/Elle其能力也仅限于此了(不完备和随机是两大弊端)。如采用Jepsen/Elle能发现一个系统存在较多问题,其实应该反观该系统的设计和实现质量了(这也说明前述的数据库系统需要一个完备的一致性回归验证系统的重要性,也说明了目前一致性理论的局限性;另外这里讨论的是Jepsen/Elle事务的一致性的测试能力,不是作为混沌测试的故障注入的测试能力),而不是奉Jepsen/Elle为神了。
如下内容,由ChatGPT提供,请读而笑之!
Q(问ChatGPT):在各个数据库产品中,“SELECT…FOR UPDATE”语法是在哪个产品中最先出现的?给出各个数据库的名称、对应的数据库版本号、出现该SQL语法的时间。
A(ChatGPT答):
"SELECT...FOR UPDATE"语法是用于在数据库中锁定选定的行,以防止其他事务对其进行修改。这个语法最早出现在Oracle数据库中。
以下是一些常见数据库产品中"SELECT...FOR UPDATE"语法的出现时间:
1. Oracle数据库:
- 版本:Oracle 6
- 出现时间:1988年
2. IBM DB2数据库:
- 版本:DB2 2.3
- 出现时间:1989年
3. PostgreSQL数据库:
- 版本:PostgreSQL 6.3
- 出现时间:1998年
4. MySQL数据库:
- 版本:MySQL 3.23
- 出现时间:2001年
5. Microsoft SQL Server数据库:
- 版本:SQL Server 2005
- 出现时间:2005年
需要注意的是,不同数据库产品对于"SELECT...FOR UPDATE"语法的支持和语法细节可能会有所不同。因此,在使用时请参考相应数据库产品的文档和版本说明。
那海蓝蓝备注:
1. 可串行化(Serializability)的基本概念,出现在20世纪60年代。
2. 冲突可串行化,出现在20世纪70年代。
3. 随后的几十年中,可串行化理论还在继续发展而未定型的过程中。其中数据一致性的概念一直处于模糊混乱状态中,理论缺位。
4. Oracle,数据库的龙头老大,在1988年即带头实施了“把球踢给用户的策略”,随后在1989年的DB2、1998年PostgreSQL的无奈地跟进。
5. Adya的论文《Generalized isolation level definitions》2000年发表,为Jespen提供了理论依据。可惜如3所述,理论缺位为测试工具带来硬伤。
6. 之后,在2001年的MySQL、2005年的SQL Server也无奈地跟进。
之前,我们谈到了“100%保证数据正确性”,那么, 什么是数据正确性?下一篇,我们将来谈谈这个。这个内容,有些理论化,但是理解本系列文章的基础,也是锤炼数据库内功的好机会。
[1] 李海翔,李晓燕,刘畅,杜小勇,卢卫,潘安群.数据库管理系统中数据异常体系化定义与分类.软件学报,2022,33(3):0
[2] 《Elle: Inferring Isolation Anomalies from Experimental Observations》,
第三代分布式数据库(1)——踢球时代
第三代分布式数据库(2)——创新之源