Jepsen:MySQL 8.0.34

Jepsen 对 MySQL 8.0.34 的分析重新引发了人们对该数据库事务保证的审视,显示其默认的“repeatable read”隔离仍可能产生令人意外的异常——即使在单节点上也是如此——而且厂商和用户往往误解了自己实际获得的安全级别。评论者将 MySQL 与 PostgreSQL 及其他系统在性能、复制、运维复杂度和隔离语义上进行比较,许多人认为 serializable 隔离应该成为默认值,同时也承认其性能代价。该讨论强调了现实中的系统如何建立在较弱或文档不清的一致性模型之上却仍然看似“足够好用”,以及典型开发者要正确理解隔离级别有多困难。

为什么要在 MySQL 上启动新项目?

  • 许多人使用 MySQL,是因为他们已经熟悉它,能够排查它,而且它对典型工作负载来说“足够好用”。
  • 它对大多数公司而言扩展性已经足够;更极端的场景可以使用 Vitess 之类的工具。
  • 历史上,它提供了可插拔引擎和易于复制;人们普遍认为它更容易运维,并且很适合读多写少的应用。
  • 有些人觉得它的 CLI 和工具链比替代方案更“开发者友好”。

MySQL vs PostgreSQL:功能与运维

  • PostgreSQL 因更合理的 SQL 方言、更丰富的功能(JSONB、部分/表达式索引)以及强大的生态而受到赞誉。
  • 有人认为 MySQL 在运维上更简单:升级更容易、逻辑复制由来已久、类似 autovacuum 的调优没那么痛苦。
  • 有人声称 MySQL 的 MVCC 和线程模型在技术上优于 PostgreSQL 的“每连接一个进程”加 vacuuming,尽管也有人质疑其扩展性说法。
  • PostgreSQL 的查询规划器更先进,但有时会不可预测地选出很差的计划,而且不容易强制指定;MySQL 的规划器能力较有限,但在紧急情况下被视为更可预测。

隔离级别、正确性与默认值

  • 这场讨论的核心在于:MySQL 的“Repeatable Read”并不符合形式化模型,而且即使在单节点上也会产生异常。
  • 一些人认为默认隔离级别应该是 SERIALIZABLE,因为大多数开发者并不理解隔离;较弱的级别会带来微妙、难以排查的 bug。
  • 另一些人强调 SERIALIZABLE 的性能成本和频繁的事务重试,主张只有在严格需要时才使用它。
  • 有人提出,对大多数应用来说,真正有意义的只有两个级别:READ COMMITTED 和 SERIALIZABLE;介于两者之间的东西都像是令人困惑的“无人区”。
  • 快照隔离被视为对只读查询很有价值。

开发者实践与锁

  • 许多评论者表示,开发者几乎不会去考虑隔离或一致性;他们只是接受默认值。
  • SELECT … FOR UPDATE 和显式锁可以“修复”异常,但代价是性能下降、锁争用以及潜在的死锁。
  • 在 MVCC 下,长事务或大事务被强调为重大的性能与扩展风险。

MySQL 的变体及更广泛的影响

  • 据报道,MariaDB 也会表现出与 MySQL 相同的异常类别,即使在单节点测试中也是如此。
  • Aurora MySQL 基本保留了 MySQL/InnoDB 的语义,但在共享存储和 purge 方面有一些集群特有的怪异之处。
  • 评论者觉得很惊人:有如此多“实际上能工作”的系统,竟然建立在带有这些可观察一致性瑕疵的引擎之上。