PostgreSQL 同步复制一致性

PostgreSQL synchronous replication consistency

如果我们比较多种类型的复制(Single-leader、Multi-leader 或 Leaderless),Single-leader 复制有可能是可线性化的。在我的理解中,线性化意味着一旦写入完成,所有以后的读取都应该 return 该值,或者以后的写入。或者换句话说,如果只有一个数据库,应该会有印象,但不会有更多。所以我想,没有过时的阅读。

PostgreSQL 在他的流复制中,能够使用 synchronous_standby_names 使其所有副本同步,并且还能够使用 synchronous_commit 选项进行微调,可以在其中进行设置到 remote_apply,所以领导者一直等到事务在备用数据库上重放(使其对查询可见)。在 documentation 中,在讨论 remote_apply 选项的段落中,它指出这允许在具有因果一致性的简单情况下进行负载平衡。

前几页,它说 this:

,一些解决方案是同步的,这意味着在所有服务器都提交事务之前,数据修改事务不会被视为已提交。这保证了故障转移不会丢失任何数据,并且所有负载平衡的服务器将 return 一致的结果,无论查询哪个服务器,

所以我很难理解可以保证什么,如果我们将读取查询负载平衡到只读副本,会发生什么异常。还会有过时的读取吗?当我查询不同的副本以获得不同的结果时,即使在领导者身上发生后没有写入,也会发生这种情况吗?我的印象是肯定的,但我不太确定。 如果不是,PostgreSQL 如何防止过时读取?我没有找到任何关于它如何在引擎盖下完全工作的更多细节。它是使用两阶段提交,还是对其进行了一些修改,或者它使用了一些其他算法来防止过时读取?

如果它不提供没有过时读取的选项,有没有办法实现?我看到,PgPool 必须选择对不超过定义阈值的副本进行负载平衡,但我不明白是否可以将其定义为对与领导者同步的副本进行负载平衡。

我真的很困惑,无法真正理解在 PostgreSQL 中完全同步复制是否会发生异常。

我知道像这样的设置在可用性方面存在问题,但现在这不是问题。

如果您使用 synchronous_commit = remote_apply 的同步复制,您可以确定一旦提交修改事务,您就会在备用数据库上看到修改后的数据。

同步复制不使用two-phasecommit,主服务器先在本地commit然后在COMMITreturns之前简单地等待同步备服务器的反馈。所以以下是可能的:

  • 观察者将在 COMMIT returns 之前以及数据传播到备用数据库之前在主数据库上看到修改后的数据。

  • 观察者将在主 returns 上的 COMMIT 之前看到备用数据库上的修改数据。

  • 如果提交事务在 COMMIT returns 之前的适当时刻在主服务器上中断,事务将仅在主服务器上提交。在服务器上发生提交的时间和向客户端报告的时间之间总是有一定的时间 window,但是 window 随着流复制而显着增加。

    不过,最终,数据修改总是会进入备用数据库。