细节其实很多。。。
1 到底什么是ACID
首先需要说明的是,在IT领域,很多名词在不同的上下文环境中的语义是不同的。例如某些产品宣称支持“100% ACID”和“强一致性”等。那么,这些名词到底指的是什么?如果不结合具体的语境,我们很可能产生各种误解。在没有NoSQL,也更没有NewSQL之前,我们需要关注的是数据库产品支持的隔离级别的差异,而不需要关心它们到底实现了ACID没有。因为ACID是数据库产品的根本,不同产品之间的差异可以说是微乎其微。ACID最容易导致歧义的术语就是隔离级别,不同数据库产品支持的隔离级别、SQL标准定义的隔离级别不仅在名字上有区别,在实际含义上也有区别。例如:Oracle的可串行化其实是Snapshot
Isolation1;DB2的Repeatable Read其实是Serializable2。ACID中的I(Isolation)在学术界默认指的就是可串行化,要不然问题也不会复杂到研究了几十年还有的玩。没有了可串行化,ACID中的Consistency也自然不靠谱了。文章3和4中列出了18个数据库产品,对比它们提供的默认隔离级别以及最高隔离级别。这里截个图供参考。
既然可串行化那么重要,那数据库为什么还要提供比可串行化低的隔离级别?可串行化确实在数据库不了解应用程序逻辑的情况保证数据一致性的问题。但是它是要付出代价的,往往会导致系统的性能损失。较低的隔离级别可以提高性能、可用性,也能满足应用的很多需求。例如,在基于封锁实现的系统中,读可以加短锁,从而使得事务不容易死锁或回滚。当然了,低隔离级别会导致各种各种的一致性异常2。既然存在这么多的问题,那为什么低隔离级别用得还很多呢?文章3说One
possibility is that anomalies are rare and the performance benefits of weak isolation outweigh the cost of inconsistencies. Another possibility is that applications are performing their own concurrency control external to the database; database programmers
can use commands like SELECT FOR UPDATE, manual LOCK TABLE, and UNIQUE constraints to manually perform their own synchronization. 这个解释比较符合应用开发中的实际情况。
2 高可用事务而不是CAP
文章3是VLDB2014的论文。题目"Highly Available Transactions: Virtues and Limitations"是应该仿照" J. Gray. The transaction
concept: Virtues and limitations. In VLDB 1981."起的。它考虑的是这种场景:
- 广域网环境下的HA,文章强调网络故障(网络分区)以及时延,而且试验环境也是Amazon上的LevelDB。
- 多副本,所以保证你不了可串行化。只能在弱一些的隔离级别上做。
数据库的隔离级别和分布式系统的副本一致性(transactional isolation, replica consistency)在概念上不太统一,它将这些概念以及高可用系统统一考虑。这样至少可以帮我们解决前面提到的术语含义问题。网络分区时可串行化是做不到的:Indeed, serializable transactions—the gold standard of traditional ACID databases—are not achievable with high availability
in the presence of network partitions [.27]. 不考虑HA时,传统的分布式可串行化和SI机制:We have a strong understanding of weak isolation in the single-server context from which it originated [2, 11, 37] and many papers offer techniques for providing distributed serializability
[13, 24, 26, 41, 60] or snapshot isolation [42, 58]. 这些系统实际上也是有各种各样的前提条件的。
什么是HA,论文第4节对此做出了定义:HA,Sticky A,Transactional A。定义Sticky A时又引入了全复制系统和不完全复制系统的概念。实际系统大部分都是不完全复制的。按照脚注的说明,sharding系统应该属于不完全复制的特例(每个数据只有一个副本)。至于什么是HAT,论文第5节专门描述它:HAT systems provide transactions with transactional availability or sticky transactional availability。并且列出了HAT可以做到和不能做到的语义。
HAT可以做到:
- 原子性(不管涉及到多少个节点)
- RC和RR
- 会话级别的read-your-writes,monotonic reads (i.e., time doesn’t go backwards), and causality within and across transactions
- Eventual consistency, meaning that, if writes to a data item stop, all transaction reads will eventually return the last written value
HAT做不到:
- 分区后的数据recency
- HATs cannot be “100% ACID compliant” as they cannot guarantee serializability, yet they meet the default and sometimes maximum guarantees of many “ACID” databases.
- HATs cannot guarantee global integrity constraints (e.g., uniqueness constraints across data items) but can perform local checking of predicates (e.g., per-record integrity maintenance like null value checks).
3 列出所有的现象/异常
- 传统数据库隔离级别相关的现象/异常。
- P0, Dirty Write
- P1, Dirty Read
- P2, Non-repeatable Read, Fuzzy Read
- P3, Phantom,注意包括插入、删除和更新三种情况
- P4, Lost Update
- A5 (Data Item Constraint Violation)
- A5A Read Skew
- A5B Write Skew
- A Critique中有,但是这里没有单独列出来的:P4C,A1,A2,A3。
- MAV,读到事务的原子的修改
- RA,Read Atomic isolation,类似Oracle的TSC
- 会话相关的现象/异常。
- Read Your Writes
- Monotonic Writes
- Monotonic Reads
- Writes Follow Reads
- Pipelined Random Access Memory (是上面前三者的组合)
- Causal consistency(是上面前四者的组合,也就是PRAM和Writes Follow Reads的组合)
- 分布式系统一致性相关的现象/异常。
- Recency(这个似乎是多出来的,应该不算)
- Safe Register
- Regular Register
- Linearizability
- 可串行化
- 传统的可串行化定义的是单副本的场景。
- 在多副本的场景下,定义One-copy可串行化。
- 它与Linearizability一起构成了严格可串行化。
Footnotes:
1
http://iggyfernandez.wordpress.com/2010/09/20/dba-101-what-does-serializable-really-mean/
2
http://research.microsoft.com/pubs/69541/tr-95-51.pdf
3
http://www.bailis.org/blog/hat-not-cap-introducing-highly-available-transactions/
4
http://www.bailis.org/blog/when-is-acid-acid-rarely/