首页 > 解决方案 > PostgreSQL 同步复制一致性

问题描述

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

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

几页后,它

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

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

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

真正理解 PostgreSQL 中的完全同步复制是否会发生异常让我感到非常困惑。

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

标签: postgresqlreplicationpgpool

解决方案


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

同步复制不使用两阶段提交,主服务器先在本地提交,然后简单地等待同步备用服务器的反馈后再COMMIT返回。所以以下是可能的:

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

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

  • COMMIT如果提交事务在返回前的适当时刻在主节点上中断,则事务将仅在主节点上提交。在服务器上发生提交和向客户端报告的时间之间总是有一个特定的时间窗口,但是随着流复制,该窗口会大大增加。

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


推荐阅读