【问题标题】:PostgreSQL synchronous replication consistencyPostgreSQL 同步复制一致性
【发布时间】:2020-09-02 07:37:08
【问题描述】:

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

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

几页后,上面写着this

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

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

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

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

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

【问题讨论】:

    标签: postgresql replication pgpool


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 不难推断,当您收到响应时,每个进一步的请求都应该看到数据。我尝试在前面使用pg_pool的集群上使用tc工具模拟一些网络延迟,我观察到即使master没有返回也可以在replica上查询数据。我的理解是,如果复制使用 2pc,副本上的提交将在不同时间执行,因此在很小的间隔内,负载平衡可能会产生最新的读取,然后是陈旧的读取。我说的对吗?
    • 我在我太短的答案中添加了一些细节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多