本文是一篇CockroachDB官方博客的译文,主要阐述数据库实现串行化隔离的必要性。关于事务隔离性,Ivan曾经在“分布式数据库之事务隔离性”中从理论方面进行过系统的介绍,本文则是从数据库厂商的角度来阐述对隔离性的理解,你们能够将两篇文章结合起来,对隔离性有更加全面客观的理解。CockroachDB的理念是首先保证安全性然后追求高性能,因此花了很大精力实现Serializable Snapshot Isolation
,是目前极少的有实用价值的SERIALIZABLE
实现。固然,业界也有厂商对可串行化方面投入的必要性持不一样观点。Ivan猜想CockroachDB的理念多是受到了PostgreSQL的影响,毕竟后者是率先支持Serializable Snapshot Isolation
的商业数据库,而且CockroachDB在SQL层面也是以兼容PostgreSQL为目标。sql
大多数数据库都提供了事务隔离级别的选择,能够在正确性和性能之间进行权衡。然而,高性能的代价就是开发人员必须当心研究事务交互不然就会引入一些微妙的错误。CockroachDB 默认提供了强隔离(SERIALIZABLE
)能够确保你的应用老是看到指望的数据。在本文中咱们将解释这意味着什么以及不充分的隔离在如何影响真实世界的应用。数据库
SQL标准定义四个隔离级别浏览器
SERIALIZABLE
安全
REPEATED READ
并发
READ COMMITTED
分布式
READ UNCOMMITTED
工具
SERIALIZABLE
事务运行时好像在同一时刻仅有一个事务运行;其余隔离级别容许出现SQL标准称做的“三种phenomena”脏读、不可重复读、幻读。后续的研究(此处指Critique,Ivan在文章“分布式数据库之事务隔离性”中已经进行了介绍)定义了额外的“phenomena”和隔离级别。
在现代研究中,这些“phenomena”更广泛被称为“anomalies”,或者更直接称为”lies”。当你使用一个非SERIALIZABLE
隔离级别时,你是在容许数据库返回错误答案,但愿它能比正确答案更快。SQL标准认为这是危险的,须要SERIALIZABLE
置为默认的隔离级别。更弱的隔离级别只是为那些能够容忍“anomalies”的应用提供了潜在的优化手段。性能
多数的数据库忽略了将 SERIALIZABLE
做为默认隔离级别的规约,而是默认替换为更弱的RC
或RR
隔离级别,它们的性能优先于安全性。更使人担忧的是,一些数据库(包括Oracle,PostgreSQL V9.1之前)根本不提供 SERIALIZABLE
级别的事务隔离。Oracle实现的 SERIALIZABLE
隔离级别其实是更弱的“Snapshot Isolation
”。Snapshot Isolation
(快照隔离,简称SI
)的出现晚于SQL标准的制定,可是已经被多种数据库系统实现,由于它提供了很好的性能与一致性的平衡。它强于RC
但弱于 SERIALIZABLE
,很相似RR
但不彻底等同(RR
容许幻读,但禁止写偏序,SI
更好相反)。实现SI
的数据库,在如何将其归入到四个SQL标准隔离级别上有不一样的选择。Oracle的选择最激进,直接将他们的SI
实现称为 SERIALIZABLE
。CockroachDB 和SQL Server则保守一些,将SI
做为独立的第五个隔离级别。PostgreSQL(9.1版本之后)介于二者之间,使用SI
替换了RR
。由于数据库不多使用 SERIALIZABLE
模式,而是默认采用更弱的隔离级别,因此它一般不多通过完全的测试和优化。例如PostgreSQL有一个固定大小的内存池,用来跟踪可串行化事务间的冲突,但在高负载状况下会耗尽。
多数的数据库厂商将更强的事务隔离做为给应用程序的一个特殊选项用于应对额外的一致性需求。多数应用程序被认为能够运行在更快可是不安全的弱隔离模式下。这种处理问题的落后方式致使将应用程序暴露在大量细微的bug中。在Cockroach Labs,咱们喜欢思考事务anomalies,以致于咱们用它们来命名会议室。但我很难有信心的建议何时选择 SI
替代 SERIALIZABLE
是安全有益的。
咱们的哲学是从安全性出发向着高性能方向前进,这是比其余方式更优的。学习
斯坦福最近的研究展现了弱隔离性对真实世界的影响程度。 Todd Warszawski and Peter Bailis测试了12个电子商务应用程序并发现了22个事务相关的Bug,其中5个在更高的隔离级别下能够避免。多数bug能够被简单得利用并形成财务方面的影响。例如,在5个被测试的应用程序中,当操做一个浏览器进行结算的同时,操做另外一个浏览器向购物车增长一项商品,可能致使新增的商品在帐单中免费。这些研究人员开发工具以半自动化的方式去肯定这些脆弱点,为相似的更广泛的攻击(研究者将其称为ACIDRain “酸雨”)铺平了道路。
大多数默认弱隔离的数据库都提供了解决方法,例如 FOR UPDATE
和 LOCK IN SHARE MODE
(非标准语法)做为SQL语句的修饰符。当正确使用时,即便在弱隔离级别下,这些修饰符也可使事务安全。然而,这很容易出错,并且即便是使用这些扩展方式,也会同时引入 SERIALIZABLE
模式大多数的缺点。(事实上,在RC
事务中滥用 SELECT FOR UPDATE
能够致使比 SERIALIZABLE
更差的性能,由于在那些串行化操做的地方能够仅使用共享锁,却使用了排他锁) ACIDRain的研究显示了这种技术的局限性:3个应用程序中仅有一个正确使用了 SELECT FOR UPDATE
特性,其余两个都存在漏洞。开发工具
鼓励弱隔离级别(性能优先于数据安全性)的数据库,让你去学习事务间细微的交互并实现易错的解决方法。CockroachDB默认提供了 SERIALIZABLE
事务,确保总能看到你所指望的事务数据库的一致性
原文连接 https://www.cockroachlabs.com/blog/acid-rain/