为什么 CockroachDB 不使用 EvalPlanQual

主要观点:

  • PostgreSQL 在 READ COMMITTED 隔离级别下,执行 UPDATE、DELETE、SELECT FOR UPDATE 或 SELECT FOR SHARE 语句时有时会错过行,这是由于添加了 EvalPlanQual 重查以防止丢失更新异常。
  • CockroachDB 的新 READ COMMITTED 隔离实现使用不同技术避免错过行,减轻了应用级重试的需求。
  • PostgreSQL 的 EvalPlanQual 策略通过在锁定所有符合条件的行后重新评估查询步骤来防止丢失更新,但会错过某些行,导致应用级重试。
  • CockroachDB 的策略是在写入意向时如果遇到较新的行版本则回滚并重新开始,通过整个语句的重试可以获取所有变化,且在重试期间保持锁和意向。
  • 从应用角度看,使用 PostgreSQL 时应用需进行重试,而 CockroachDB 可隐藏重试,避免了应用级重试的开销。

关键信息:

  • PostgreSQL 防止丢失更新的步骤及会错过行的原因。
  • CockroachDB 防止丢失更新的步骤及内部语句重试机制。
  • 不同数据库在 READ COMMITTED 隔离级别下的行为差异,如 PostgreSQL 会错过行,MySQL 有类似情况,Oracle 行为更接近 CockroachDB。

重要细节:

  • PostgreSQL 的 EvalPlanQual 重查包括建立读取快照、扫描、过滤、锁定、重新读取锁定行的最新版本、重新运行过滤器并写入新版本。
  • CockroachDB 的策略包括创建保存点、建立读取快照、扫描、过滤、写入意向,遇到较新行版本时回滚并重新开始。
  • 应用级重试比数据库级重试更昂贵,CockroachDB 可隐藏重试。
  • Intents 是作为排他锁的行的新版本。在 SERIALIZABLE 隔离级别下,CockroachDB 遇到可序列化历史无法实现时会重试整个事务,此案例中单个语句的隐式事务在两种隔离级别下行为相似,但场景不同时隔离级别会显示不同行为。
阅读 14
0 条评论