MySQL与PostgreSQL在事务隔离上的差异

2020-06-17 00:00:00 版本 事务 并发 隔离 论文

前言:主流的开源数据源产品如MySQL、PostgreSQL虽然都各自实现了Repeatable Read、Serializable 事务隔离级别,不过他们在概念上或者实现方式上还是存在一定差异,本文旨在通过实际测验来对比两块数据库产品在实现上的差异。

在《A Critique of ANSI SQL Isolation Levels》论文中描述了事务不同隔离级别下异常现象,总结出的结论如图:

这里主要对比P3、P4、A5B现象表现上存在差异

论文中对A5B、P3、P4的定义如下:

A5B Write Skew Suppose T1 reads x and y, which are consistent with C(), and then a T2 reads x and y, writes x, and commits. Then T1 writes y. If there were a constraint between x and y, it might be violated. In terms of histories: A5B: r1[x]...r2[y]...w1[y]...w2[x]...(c1 and c2 occur) (Write Skew)

P3: SQL-transaction T1 reads the set of rows N that satisfy some <search condition>. SQL-transaction T2 then executes SQL-statements that generate one or more rows that satisfy the <search condition> used by SQL-transaction T1. If SQL-transaction T1 then repeats the initial read with the same <search condition>, it obtains a different collection of rows.
r1[P]...w2[y in P]...((c1 or a1) and (c2 or a2) any order)

P4 (Lost Update): The lost update anomaly occurs when transaction T1 reads a data item and then T2 updates the data item (possibly based on a previous read), then T1 (based on its earlier read value) updates the data item and commits. In terms of histories, this is:

P4: r1[x]...w2[x]...w1[x]...c1 (Lost Update)

下面分别测试MySQL、PostgreSQL 在Repeatable Read 、Serializable 隔离级别下A5B、P3现象的差异

MySQL Repeatable Read

MySQL版本5.7

MySQL Repeatable Read 下够避免A5B

MySQL Repeatable Read 下不能避免P3

MySQL Repeatable Read 下不能避免P4

PostgreSQL Repeatable Read

PostgreSQL版本10

PostgreSQL Repeatable Read 下不能够避免A5B

PostgreSQL Repeatable Read 下避免P3

PostgreSQL Repeatable Read 下避免P4

MySQL Serializable

MySQL版本5.7

MySQL Serializable 下避免P3

PostgreSQL Serializable

PostgreSQL版本10

PostgreSQL Serializable下够避免A5B

结论:

  • 通过上面测验可以看出MySQL innodb中实现的Repeatable Read与论文中定义的Repeatable Read不一致:能够避免A5B(写倾斜);不能避免P3(幻读)和P4(丢失更新,RR隔离级别下innodb读的时候是快照读,但是写的时候采用的是当前读,也就是更新的时候,不再考虑快照,而是基于新的版本来更新);
  • 而PostgreSQL中的Repeatable Read也与论文中定义的不一致:能够避免P3(幻读)而不能避免A5B(写倾斜),实际上PostgreSQL中实现的Repeatable Read与论文中定义的Snapshot一致;
  • MySQL利用SS2PL读阻塞写进而消除P3、P4实现了Serializable ,但事务并发度较差;
  • 而PostgreSQL在Snapshot基础上通过检测读写冲突,发现冲突后回滚一个事务进而消除A5B实现了Serializable Snapshot,事务并发度相较SS2PL实现的Serializable要好很多。
  • PostgreSQL和MySQL innodb在事物的并发控制上都采用了SS2PL+MVCC,PostgreSQL更倾向于使用后者,而MySQL innodb 更倾向使用前者。

参考:

A Critique of ANSI SQL Isolation Levelsipads.se.sjtu.edu.cn

相关文章