数据库事务隔离发展历史

事务隔离是数据库系统设计中根本的组成部分,本文主要从标准层面来讨论隔离级别的发展历史,首先明确隔离级别划分的目标;之后概述其否定之否定的发展历程;进而引出 Adya给出的比较合理的隔离级别定义,最终总结隔离标准一路走来的思路。

目标

事务隔离是事务并发产生的直接需求,最直观的、保证正确性的隔离方式,显然是让并发的事务依次执行,或是看起来像是依次执行。但在真实的场景中,有时并不需要如此高的正确性保证,因此希望牺牲一些正确性来提高整体性能。通过区别不同强度的隔离级别使得使用者可以在正确性和性能上自由权衡。随着数据库产品数量以及使用场景的膨胀,带来了各种隔离级别选择的混乱,数据库的众多设计者和使用者亟需一个对隔离级别划分的共识,这就是标准出现的意义。一个好的隔离级别定义有如下两个重要的目标

  • 正确:每个级别的定义,应该能够将所有损害该级别想要保证的正确性的情况排除在外。也就是说,只要实现满足某一隔离级别定义,就一定能获得对应的正确性保证。
  • 实现无关:常见的并发控制的实现方式包括,锁、OCC以及多版本 。而一个好的标准不应该限制其实现方式。

ANSI SQL标准(1992):基于异象

1992年ANSI首先尝试指定统一的隔离级别标准,其定义了不同级别的异象(phenomenas), 并依据能避免多少异象来划分隔离标准。异象包括:

  • 脏读(Dirty Read): 读到了其他事务还未提交的数据;
  • 不可重复读(Non-Repeatable/Fuzzy Read):由于其他事务的修改或删除,对某数据的两次读取结果不同;
  • 幻读(Phantom Read):由于其他事务的修改,增加或删除,导致Range的结果失效(如where 条件查询)。

通过阻止不同的异象发生,得到了四种不同级别的隔离标准

ANSI SQL标准看起来是非常直观的划分方式,不想要什么就排除什么,并且做到了实现无关。然而,现实并不像想象美好。因为它并不正确

A Critique of ANSI(1995):基于锁

几年后,微软的研究员们在A Critique of ANSI SQL Isolation Levels一文中对ANSI的标准进行了批判,指出其存在两个致命的问题:

1,不完整,缺少对Dirty Write的排除

ANSI SQL标准中所有的隔离级别都没有将Dirty Write这种异象排除在外,所谓Dirty Write指的是两个未提交的事务先后对同一个对象进行了修改。而Dirty Write之所以是一种异象,主要因为他会导致下面的一致性问题:

H0: w1[x] w2[x] w2[y] c2 w1[y] c1

这段历史中,假设有相关性约束x=y,T1尝试将二者都修改为1,T2尝试将二者都修改为2,顺序执行的结果应该是二者都为1或者都为2,但由于Dirty Write的发生,最终结果变为x=2,y=1,不一致。

2,歧义

ANSI SQL的英文表述有歧义。以Phantom为例,如下图历史H3:

H3:r1[P] w2[insert y to P] r2[z] w2[z] c2 r1[z] c1

假设T1根据条件P查询所有的雇员列表,之后T2增加了一个雇员并增加了雇员人数值z,之后T1读取雇员人数z,最终T1的列表中的人数比z少,不一致。但T1并没有在T2修改链表后再使用P中的值,是否就不属于ANSI中对Phantom的定义了呢?这也导致了对ANSI的表述可能有严格和宽松两种解读。对于Read Dirty和Non-Repeatable/Fuzzy Read也有同样的问题。

那么,如何解决上述两个问题呢?Critique of ANSI的答案是:宁可错杀三千,不可放过一个,即给ANSI标准中的异象最严格的定义。Critique of ANSI改造了异象的定义:

P0: w1[x]…w2[x]…(c1 or a1) (Dirty Write)P1: w1[x]…r2[x]…(c1 or a1) (Dirty Read)
P2: r1[x]…w2[x]…(c1 or a1) (Fuzzy or Non-Repeatable Read)
P3: r1[P]…w2[y in P]…(c1 or a1) (Phantom)

此时定义已经很严格了,直接阻止了对应的读写组合顺序。仔细可以看出,此时得到的其实就是基于锁的定义:

  • Read Uncommitted,阻止P0:整个事务阶段对x加长写锁
  • Read Commited,阻止P0,P1:短读锁 + 长写锁
  • Repeatable Read,阻止P0,P1,P2:长读锁 + 短谓词锁 + 长写锁
  • Serializable,阻止P0,P1,P2,P3:长读锁 + 长谓词锁 + 长写锁

问题本质

可以看出,这种方式的隔离性定义保证了正确性,但却产生了依赖实现方式的问题:太过严格的隔离性定义,阻止了Optimize或Multi-version的实现方式中的一些正常的情况

  • 针对P0:Optimize的实现方式可能会让多个事务各自写自己的本地副本,提交的时候只要顺序合适是可以成功的,只在需要的时候才abort,但这种选择被P0阻止;
  • 针对P2:只要T1没有在读x,后续没有与x相关的操作,且先于T2提交。在Optimize的实现中是可以接受的,却被P2阻止。

回忆Critique of ANSI中指出的ANSI标准问题,包括Dirty Write和歧义,其实都是由于多Object之间有相互约束关系导致的,如下图所示,图中黑色部分表示的是ANSI中针对某一个异象描述的异常情况,灰色部分由于多Object约束导致的异常部分,但这部分在传统的异象定义方式中并不能描述,因此其只能退而求其次,扩大限制的范围到黄色部分,从而限制了正常的情况。

由此,可以看出问题的本质由于异象的描述只针对单个object,缺少描述多object之间的约束关系,导致需要用锁的方式来作出超出必须的限制。相应地,解决问题的关键:要有新的定义异象的模型,使之能精准的描述多object之间的约束关系,从而使得我们能够精准地限制上述灰色部分,而将黄色的部分解放出来。Adya给出的答案是序列化图。

A Generalized Theory(1999):基于序列化图

Adya在Weak Consistency: A Generalized Theory and Optimistic Implementations for Distributed Transactions中给出了基于序列化图得定义,思路为先定义冲突关系;并以冲突关系为有向边形成序列化图;再以图中的环类型定义不同的异象;最后通过阻止不同的异象来定义隔离级别。

序列化图(Direct Serialization Graph, DSG)

序列化图是用有向图的方式来表示事务相互之间的依赖关系,图中每个节点表示一个事务,有向边表示存在一种依赖关系,事务需要等到所有指向其的事务先行提交,如下图所示历史的合法的提交顺序应该为:T1,T2,T3:

这里的有向边包括三种情况:

  • 写写冲突ww(Directly Write-Depends):表示两个事务先后修改同一个数据库Object(w1[x]…w2[x]...);
  • 先写后读冲突wr(Directly Read-Depends):一个事务修改某个数据库Object后,另一个对该Object进行读操作(w1[x]…r2[x]...);
  • 先读后写冲突rw(Directly Anti-Depends):一个事务读取某个Object或者某个Range后,另一个事务进行了修改(r1[x]…w2[x]… or r1[P]…w2[y in P]);

基于序列化图的异象定义:

根据有向图的定义,我们可以将事务对不同Object的依赖关系表示到一张同一张图中,而所谓异象就是在图中找不到一个正确的序列化顺序,即存在某种环。而这种基于环的定义其实就是将基于Lock定义的异象最小化到图中灰色部分:

1,P0(Dirty Write) 最小化为 G0(Write Cycles):序列化图中包含两条边都为ww冲突组成的环,如H0:

H0: w1[x] w2[x] w2[y] c2 w1[y] c1

可以看出T1在x上与T2写写冲突,T2又在y上与T1写写冲突,形成了如下图所示的环。

2,P1(Dirty Read) 最小化为 G1:Dirty Read异象的最小集包括三个部分G1a(Aborted Reads),读到的uncommitted数据最终被abort;G1b(Intermediate Reads) :读到其他事务中间版本的数据;以及G1c(Circular Information Flow):DSG中包含ww冲突和wr冲突形成的环。

3,P2(Fuzzy or Non-Repeatable Read) 最小化为 G2-item(Item Anti-dependency Cycles) :DSG中包含环,且其中至少有一条关于某个object的rw冲突

4,P3(Phantom) 最小化为 G2(Anti-dependency Cycles): DSG中包含环,并且其中至少有一条是rw冲突,仍然以上面的H3为例:

H3:r1[P] w2[insert y to P] r2[z] w2[z] c2 r1[z] c1

T1在谓词P上与T2 rw冲突,反过来T2又在z上与T1wr冲突,如下图所示:

对应的隔离级别:

通过上面的讨论可以看出,通过环的方式我们成功最小化了异象的限制范围,那么排除这些异象就得到了更宽松的,通用的隔离级别定义:

  • PL-1(Read Uncommitted):阻止G0
  • PL-2(Read Commited):阻止G1
  • PL-2.99(Repeatable Read):阻止G1,G2-item
  • PL-3(Serializable):阻止G1,G2

其他隔离级别:

除了上述的隔离级别外,在正确性的频谱中还有着大量空白,也就存在着各种其他隔离级别的空间,商业数据库的实现中有两个比较常见:

1,Cursor Stability

该隔离界别介于Read Committed和Repeatable Read之间,通过对游标加锁而不是对object加读锁的方式避免了Lost Write异象。

2, Snapshot Ioslation

事务开始的时候拿一个Start-Timestamp的snapshot,所有的操作都在这个snapshot上做,当commit的时候拿Commit-Timestamp,检查所有有冲突的值不能再[Start- Timestamp, Commit-Timestamp]被提交,否则abort。长久以来,Snapshot Ioslation一直被认为是Serializable,但其实Snapshot Ioslation下还会出现Write Skew的异象。之后的文章会详细介绍如何从Snapshot Ioslation出发获得Serializable。

总结

对于事务隔离级别的标准,数据库的前辈们进行了长久的探索:

  • ANSI isolation levels定义了异象标准,并根据所排除的异象,定义了,Read Uncommitted、Read Committed、Repeatable Read、Serializable四个隔离级别;
  • A Critique of ANSI SQL Isolation Levels认为ANSI的定义并没将有多object约束的异象排除在外,并选择用更严格的基于Lock的定义扩大了每个级别限制的范围;
  • Weak Consistency: A Generalized Theory and Optimistic Implementations for Distributed Transactions认为基于Lock的定义过多的扩大了限制的范围,导致正常情况被排除在外,从而限制了Optimize类型并行控制的使用;指出解决该问题的关键是要有模型能准确地描述这种多Object约束;并给出了基于序列化图的定义方式,将每个级别限制的范围最小化。

参考

A History of Transaction Histories

ANSI isolation levels

A Critique of ANSI SQL Isolation Levels

Weak Consistency: A Generalized Theory and Optimistic Implementations for Distributed Transactions

Generalized Isolation Level Definitions

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么游戏行业喜欢用PolarDB

为什么游戏行业喜欢用PolarDB 游戏行业痛点 在我看来, 不同行业对数据库使用有巨大的差别. 比如游戏行业没有复杂的事务交易场景, 他有一个非常大的blob 字段用于存储角色的装备信息, 那么大Blob 字段的更新就会成为数据库的瓶颈, 比如在线教育行业需要有抢课的需求, 因此会有…

从业务开发中学习和理解架构设计

前言 在软件开发领域经常会接触到架构这个词汇,在我最初的印象中,架构是一个很高级的词汇。它似乎代表了复杂的工程结构、高层次的抽象设计、最新的开发语言特性等等。对于当时只专注于写业务逻辑的我来说,不免心生对架构的敬畏。工作中对架…

腾讯云联合中国联通打造下一代IDC数字化运营应用

近日,腾讯云联合中国联通智网创新中心打造的下一代IDC数字化运营应用,正式亮相2022中国联通合作伙伴大会。立足双方资源和经验优势,该数字化应用可实现对数据中心电力系统、制冷环境、安全防范等全方位智慧化运营,助力中国联通推进…

研发效能的思考总结

前言 在谈效能之前,我想先谈谈作为一个技术人或者技术TL,研发的核心价值是什么? 之前看了一篇文章,比较有意思,分享一下观念: T外包公司:最核心的竞争力不是技术,而是快速响应、资…

以“升舱”之名,谈谈云原生数据仓库 AnalyticDB 的核心技术

背景 说到升舱,我们首先想到的是飞机经济舱升级到商务舱、头等舱。阿里云企业级云原生数据仓库AnalyticDB(以下简称ADB)[1]在帮助以金融机构为主的行业数字化转型和传统数仓升级项目中,也引用了“升舱(仓)…

阿里云联合平行云推出云XR平台,支持沉浸式体验应用快速落地

近日,阿里云与平行云联合发布云XR平台,降低云端视觉计算应用的开发门槛,加速数字孪生、虚拟人、虚拟现实、沉浸式体验与虚拟仿真平台等XR应用落地,帮助互联网、新零售、社交、工业、交通、城市管理等行业探索创新业务形态。 阿里…

放弃笨重的 IDE,转而尝试 Emacs

【编者按】IDE对于开发者而言,重要性不言而喻,但随着功能愈发强大,它们对硬件的要求也日益提高,甚至越好用的 IDE 就越笨重。链接:https://renato.athaydes.com/posts/switching-from-heavyweight-ides-to-emacs.html声…

“穿越”到虚拟世界笑风生,网易瑶台沉浸式活动平台创新云端活动体验

2020年,第二届分布式人工智能国际会议(DAI 2020)因疫情的到来险些无法举办,南京大学人工智能学院的俞扬老师通过与网易伏羲团队的合作,最终在网易旗舰级武侠端游《逆水寒》中顺利举行了本次会议。300余位全球人工智能领…

云上解锁Web3.0 阿里云XR平台助力彼真科技呈现沉浸式演唱会

摘要:通过将沉浸式演唱会应用托管到云XR平台上,彼真科技也无需像传统应用一样做大量的终端适配工作,通过Web协议即可将虚拟演唱会《故障四方》的国风科幻世界呈现在不同的终端上。云XR平台完成了算力调度、渲染、推流、编码和用户管理等工作&…

这种精度高,消耗资源少的大模型稀疏训练方法被阿里云科学家找到了!

近日,阿里云机器学习PAI关于大模型稀疏训练的论文《Parameter-Efficient Sparsity for Large Language Models Fine-Tuning》被人工智能顶会IJCAI 2022接收。 论文提出了一种参数高效的稀疏训练算法PST,通过分析权重的重要性指标,得出了其拥有…

兼顾时尚与商务? ThinkPad Z 重新定义“商务本”

因为疫情等不确定因素,在过去三年中,混合办公模式已经成为职场的新常态。新一代工作族的商务办公笔记本不仅要随身携带完成日常工作,一些人还可能“身兼数职”,在工作之余也需要笔记本的配合。办公室里严谨、内敛商务本设计&#…

Go原生插件使用问题全解析

导言 本人在设计和落地基于Go原生插件机制的扩展开发产品时踩到了很多坑,由于这方面相关资料很少,因而借此机会做一个非常粗浅的总结,希望能对大家有所帮助。 本文只说问题和解决方案,不读代码。 一些背景知识 2.1 运行时 通…

从云计算到函数计算

从云计算到函数计算 函数计算,你的名字 云计算,是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需求提供给计算机各种终端和其他设备,使用服务商提供的电脑基建作计算资源,因此用…

基于 OPLG 从 0 到 1 构建统一可观测平台实践

应用架构与可观测技术演进历程 在软件开发早期,单体应用架构因其结构简单,便于测试和部署,得到了广泛的应用,对应的监控诊断技术主要是基于日志和日志关键词的指标监控。随着软件复杂度的不断提升,单体应用架构逐步向分…

从运维到运维大神,只需要一个正确的选择

马上就是7月24日了,听群里的朋友说,7和24这两个数字是运维工作的最佳体现——7X24小时待命,所以咱们IT人将这一天自定义为“运维日”。 对于运维工作来说,想要在黑天鹅横飞,灰犀牛直撞的当下,既能独善其身…

主流定时任务解决方案全横评

定时任务作为一种按照约定时间执行预期逻辑的通用模式,在企业级开发中承载着丰富的业务场景,诸如后台定时同步数据生成报表,定时清理磁盘日志文件,定时扫描超时订单进行补偿回调等。 程序开发人员在定时任务领域有着诸多框架和方…

基于阿里云 Serverless 函数计算开发的疫情数据统计推送机器人

一、Serverless函数计算 什么是Serverless? 在《Serverless Architectures》中对 Serverless 是这样子定义的: Serverless was first used to describe applications that significantly or fully incorporate third-party, cloud-hosted applications…

看 Serverless Task 如何解决任务调度可观测性中的问题

在上篇文章《解密函数计算异步任务能力之「任务的状态及生命周期管理」》中,我们介绍了任务系统的状态管理,并介绍了用户应如何根据需求,对任务状态信息进行实时的查询等操作。在本篇中我们将会进一步走进函数计算异步任务,介绍异…

B站每日自动签到传统单节点网站的 Serverless 上云

什么是函数?刚刚考完数学没多久的我,脑力里立马想到的是自变量、因变量、函数值,也就是yf(x)。当然,在计算机里,函数function往往指的是一段被定义好的代码程序,我们可以通过传参调用这个定义好的函数&…

通过部署流行 Web 框架掌握 Serverless 技术

大家好,我是霍大侠,这个系列课程我们通过部署流行web框架,来学习掌握serverless的技术和架构。课程主要从实践介绍,实践演示,分析详解三个大的章节来一步一步学习。 前言 进入实验室-动手实践 点击下面链接进入阿里云…