写点什么

聊一聊事务的历史

  • 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:172619
用户头像

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

关注

评论

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

信也科技 x StarRocks:打造统一销售数据平台

StarRocks

数据库 高并发 StarRocks

智慧社区综合管理平台解决方案,智慧社区一体化管理系统开发

电微13828808271

数字人民币生态体系进一步完善 试点场景加速拓展

CECBC

架构实战营4期-第1周作业

周念

「架构实战营」

vue单页面和多页面的区别?

CRMEB

Python Qt GUI设计:5种事件处理机制(提升篇—3)

不脱发的程序猿

Python qt PyQt GUI设计 事件处理机制

同程旅行 IAST 落地实践

火线安全

DevOps DevSecOps 漏洞扫描 漏洞分析

IT 好文&好课分享

hackstoic

可视化埋点在 React Native 中的实践

Shopee技术团队

大前端 可视化 埋点 React Native

区块链电子签章平台搭建,区块链电子合同系统

电微13828808271

架构实战营 - 微信业务架构 & 学生管理系统

阿门阿前一颗葡萄树๑

架构实战营 #架构实战营 「架构实战营」

被寄予厚望的区块链在数据交易中能发挥的作用是什么?

CECBC

xxxx

guangbao

创业团队组织建设-跨部门沟通

wood

创业 沟通 28天写作

流上机器学习,星环科技Sophon Base助力海洋石油富岛工艺监测智能化

星环科技

Python Qt GUI设计:QTabWidget、QStackedWidget和QDockWidget容器控件类(提升篇—2)

不脱发的程序猿

Python qt PyQt GUI设计 容器控件类

vivo 敏感词匹配系统的设计与实践

vivo互联网技术

服务器 内容审核 架构设计实战 文本检测

星环科技分布式文件系统TDFS大揭秘(上)

星环科技

大数据 计算与存储

5.《重学JAVA》--编码规范

杨鹏Geek

Java 25 周年 28天写作 12月日更

Android C++系列:Linux线程(三)线程属性

轻口味

android 28天写作 12月日更

Hoo虎符研究院 | 区块链简报 20211206 期

区块链前沿News

虎符 Hoo虎符

TypeScript 之映射类型

冴羽

JavaScript typescript 翻译 大前端

未来“数”于你 | 墨天轮携手 Vertica 发布技术文章征集令,双重大奖蓄势待“发”

墨天轮

数据库 征文大赛 vertica

质量基础设施“一站式”服务信息平台建设,NQI一站式服务平台

电微13828808271

实用机器学习笔记五:探索性数据分析

打工人!

机器学习 学习笔记 12月日更 李沐 实用机器学习

Hoo虎符研究院 | 币圈后浪——KBOX

区块链前沿News

虎符 Hoo虎符 Hoo 虎符交易所

从航海贸易到元宇宙,从公司制到DAO

CECBC

数研所已实现在数字人民币中积极探索区块链应用

CECBC

AI模型也需要资产管理,星环科技重磅推出AI运营平台MLOps 星环科技 星环科技

星环科技

AI

架构模式及其应用 | 内部分享

空空

内容合集 签约计划第二季

【技术分享】DOSM Web项目优化分析 & 解决方案

云智慧AIOps社区

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