写点什么

聊一聊事务的历史

  • 2018-04-19
  • 本文字数:2671 字

    阅读完需:约 9 分钟

本文最初发布于 Arjun Narayan 的博客,经原作者授权由聊聊架构翻译并分享。

我花了相当多的精力来理解数据库的事务,最近也与 Justin Jaffray 一起研究了该话题。本文总结了我们在这期间的所学。

数据库及分布式基础架构的相关社区花了数十年来理解事务的本质这一反复出现的问题。在阅读相关文献时需要读者理解其中的背景,不然就会被其中诸多矛盾的术语及认知所迷惑。为了澄清这点,下文阐述了数据库事务相关论述的演变过程。

在一开始(1990 年?),数据库连接还极其简单粗暴。在丛林法则下,没有行业标准的数据库与使用它们的程序员们必须处理许多异常现象。为了解决这些问题,ANSI SQL-92 标准首次尝试统一定义事务隔离级别。该标准选择了如下方式:

1. 存在一些已知的异常现象,即脏读不可重复读幻读
2. 可以利用一些锁策略来防止部分甚至全部上述的异常现象。它们被称为“读未提交”(不进行隔离)、“读已提交”(没有脏读)、可重复读(没有脏读及不可重复读)。
3. 最终的隔离级别避免了全部三种异常现象。它被称为可串行化(serializable),但是这和字面意思有些出入。暂且可以认为这是整个标准中的一个缺陷。

可串行化的历史相当久远。其定义可追溯到 20 世纪 60 年代,并通过 _ 事务中的历史记录 _ 来定义。 引用 Christos Papadimitriou 在一篇早期讨论事务的论文中所述:

可串行化是指,一系列原子性的用户更新、获取操作,且其全局的效果就像用户轮流,按一定顺序,独立执行各自的事务一样。

阅读该论文有一定难度,所以简单看来, Herlihy-Wing 已很好地解释了可串行化。但是其中的思想非常简单:每一个事务就像只发生在某一瞬间,而且它们之间存在一定的顺序(但并没有说其中的顺序对用户甚至事务本身需要明确!只需要事后可回溯)。

几年之后,微软数据库团队写了一篇名为《批判ANSI SQL 隔离级别》的论文,其中指出ANSI SQL 中定义的可串行化并不是真正的可串行化!ANSI 认为,只要消除了脏读、不可重复读和幻读,就是可串行化的。这一观点是不正确的。事实证明,如果消除这三种异常现象,得到的是另一种新的隔离级别,他们称之为快照隔离。

该论文另一个有价值的贡献是指出了,通过“是否存在特定的异常现象”来界定隔离级别并不是理想的方法。接着来讨论下事务的历史记录,这段时间的相关文献都是通过定义_ 特定的锁策略_,并证明其是否会产生异常现象来定义隔离级别的。这会带来一些困惑,因为同一隔离级别可以通过多种锁策略来实现,但其隔离级别的名称又与策略是相关联的,所以同一隔离级别会存在多个名称。

这时出现了一位大神来清理这一乱局:Atul Adya 与他的博士论文《弱一致性:一个通用理论和分布式事务的的乐观实现》。Adya 从追溯事务的历史记录开始。其策略基本上是“根据一些事务的历史记录,可以研究其中变量的转变图”,然后在图中标识出一些形状(其实大部分记录的是不同的周期),并表示“这其中存在问题”。然后,将这些问题的矛头指回到ANSI 的定义上,并可以追溯到ANSI 隔离级别的一些基础的数学定义中。该论文的巨大价值在于,终于可以精确且独立于具体实现锁策略地定义隔离级别!

除了给出四个ANSI 级别的定义之外,他还指出了其它更微妙的异常情况,例如 G2 ,又称“反依赖循环”,该情况很难被察觉,其存在于快照隔离和可串行化之间的未知领域中。

Adya 的论文在数据库领域是开创性的。这是第一次连贯地通过事务中变量的转变图来给出隔离级别的数学定义。当年是 1999 年,基础设施还不完善。

接下来出现了下一个问题:当我们对事务有了更多的理解后,我们应该如何处理现存的那些混乱的数据库(即 Oracle 和 Postgres,MySQL 至今仍然只是一个玩具产品)?它们声称实现了可串行化,但实际上只是实现了快照隔离,因为它们是按 ANSI 定义来构建的。

Alan Fekete 等人在 2005 年提出了一个好办法,他们称之为“让快照隔离可串行化”。基本上就是通过一个普通的快照隔离数据库,并在 SQL 语句中进行一些校验,以确保其可串行化。他们使用 TPC-C 作为运行示例,该系统已被明确设计为始终可串行化,即使在快照隔离数据库上运行时也是如此。一般应用开发程序员,即使被迫使用的是快照隔离数据库,也可以通过这个技巧得到可串行化的隔离级别。

有了这个好想法,Fekete 在 2008 年的一篇名为《快照隔离数据库上的可串行化隔离》的论文中对这项工作进行了扩展。论文基本上是以该想法为基础,并将那些检查代码从应用程序代码中迁移到了数据库上。因此,用户不必废除已有的事务处理引擎,只需要依赖额外的校验,从而让数据库可串行化。该技术被称为SSI(可串行化快照隔离),由于采用了两个技术定义,将它们结合起来重新命名一个全新的定义并不奇怪。

在2012 年,就有开发者决定将这个好想法在 PostgreSQL 上实现,从而让 Postgres 最终拥有可串行化隔离级别。注意,这并不是默认的 postgres 模式,因为 ANSI 认为快照隔离(但仍被称为可串行化)已经足够了。需要指出ANSI 的定义并没有被修复

该策略在一篇名为《批判快照隔离》的论文中得到了延续。文中指出,SSI 引导算法可以被简化。原始的SSI 算法检查双写冲突,为了扩展,Yabandeh 建议改为检测读写冲突。虽然这需要内存中的数据结构记录每次读取的最新时间戳的信息,但对于一些日常的负载来说,其具有更好的_ 并发控制_ 能力,因为它并不会中止读取操作,而只会中止写入操作。

也正是从此,大家开始意识到他们需要关心可串行性,一部分原因是 Jeff Dean 认为其非常重要。与此同时,持续呼吁该观点将近 20 年的 Michael Stonebraker 表示很无奈,大家显然只在 Google 明星工程师声明某件事的重要性时才会关心它。

当下学者们仍有很多焦虑,因为现在我们的处境非常尴尬

1. 根据理论,可串行化是唯一的选择
2. 很多人使用非串行化的数据库,但基本上并没有遇到问题?
3. 因此,我们是否在浪费时间?可串行化是否真的有必要?我们到底需要的是什么?

Peter Bailis 在 2014 年的一篇博文中总结了这一点。他说:

尽管存在诸多的弱隔离,但我还没遇到任何数据库架构师、研究人员或用户,可以解释何时以及为什么(这可能更重要)“读已提交”的隔离级别足以满足应用的正确执行。众所周知,这些弱隔离模型代表了“实践中的 ACID”,但我认为我们并没有真正了解为何大量的应用程序看上去(!?)可以在该级别下正确运行。

反面观点多认为:那样的应用并不总能保证正常运行,当你发现问题时,就可能已经太迟了,所以不要尝试。该论点也来之不易,在大家使用 NoSQL 数据库大约十年后,该观点才开始被关注。

查看英文原文: A History of Transaction Histories

感谢郭蕾对本文的审校。

2018-04-19 18:172651
用户头像

发布了 41 篇内容, 共 13.8 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

安利一个比Gitbook更好用的国内帮助文档制作平台

Baklib

前端必读3.0:如何在 Angular 中使用SpreadJS实现导入和导出 Excel 文件

葡萄城技术团队

《软件开发的201个原则》思考:6. 低可靠性比低效率更糟糕

非晓为骁

个人成长 软件工程能力 高质量

怎样体面地讲道理?

图灵社区

写作 表达 逻辑

J神出品!让 Compose 从此摆脱 ViewModel

Java-fenn

Java java;

电商黄牛,你被小红书盯上了

小红书技术REDtech

算法 电商风控 黄牛治理

SelectDB 创始人兼 CEO 连林江荣获 OSCAR 开源产业大会「尖峰开源人物 」奖项

SelectDB

数据库 大数据 数据仓库 企业号九月金秋榜 尖峰开源

Github最新Java面试1658核心讲,助力百人入大厂!

Java-fenn

Java 编程 程序员 java面试 Java面试题

Kong重构了其事件通知机制

八苦-瞿昙

Event Gateway API Gateway

CAT 认证敏捷团队教练工作坊 (Coaching Agile Teams) | 2023年1月 7 日开课

ShineScrum

敏捷教练 专业教练

牛客网趋势最热Java八股文,速度赶紧马上打包带走!

Java-fenn

Java 编程 程序员 java面试 Java面试题

测试驱动开发 (TDD) 在线练功房 | 12 月 17 日开课

ShineScrum

TiDB Hackathon 2022丨总奖金池超 35 万!邀你唤醒代码世界的更多可能性!

PingCAP

#TiDB

数据湖系列之二 | 打造无限扩展的云存储系统,元数据存储底座的设计和实践

Baidu AICLOUD

数据湖 元数据

2021年中国自然语言处理软件及服务市场规模超200亿,市场保持高速增长,竞争格局远未稳定

易观分析

自然语言处理 市场

企业选择局域网即时通讯软件的必要性是什么?

WorkPlus

聚焦金融行业未来,博睿数据亮相第五届中国银行CIO峰会

博睿数据

AIOPS 金融 银行 博睿数据 ONE平台

我所知道的webpack5那些不太一样的改变

Java-fenn

Java

Chrome操作指南——入门篇(十一)network

Augus

Chrome开发者工具 9月月更

【9.16-9.23】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

2022年震荡与加速中前行的新消费

易观分析

疫情 消费

最全Java面试攻略,吃透25个技术栈Offer拿到手软

Java-fenn

Java 编程 程序员 java面试 Java面试题

优化帮助中心需要做到以下几点

Baklib

产品 帮助中心 在线设计

华为云GaussDB——打造金融行业坚实数据底座,共创数字金融新未来

Java-fenn

Java

当你 git push 时,极狐GitLab上发生了什么?

极狐GitLab

DevOps gitlab SSH gitops 极狐GitLab

通过 Kasten K10 by Veeam 与 SUSE Rancher 实现云原生应用灾备迁移

Java-fenn

Java

疫情时代下,线上协同办公成时下热点

Baklib

远程办公 企业 协同办公 在线设计

金九银十必备!这份java面经让你轻松拿下45kOffer

Java-fenn

Java 程序员 面试 java面试 Java面试题

WorkPlus移动办公系统:打造安全专属、统一业务与运营的企业门户

WorkPlus

日系“怎样”系列新版升级,一本书讲透程序运行的方方面面

图灵社区

Python 程序员 C语言 计算机

MyBatis批量插入几千条数据慎用foreach

Java-fenn

Java

聊一聊事务的历史_数据库_Arjun Narayan_InfoQ精选文章