gpt4 book ai didi

sql - 在 Postgres 中使用行版本实现增量客户端更新

转载 作者:太空狗 更新时间:2023-10-30 01:49:12 36 4
gpt4 key购买 nike

我是 Postgres 的新手,到目前为止我很喜欢它。我已经对这个问题进行了很多思考,RTFM 尽我所能,但进入了死胡同,所以我需要朝着正确的方向插入。

我正在设计一个数据库,其中每个感兴趣的实体都有一个 rowversion从全局序列中分配值的列。因此,在最简单的情况下,在表中 emps有两行:emp1rowversion@3emp2rowversion@5 , 我知道 emp2emp1 之后修改(即在以后的交易中——如果同一交易中的行具有相同的 rowversion 并不介意)。

这是为了形成数据同步逻辑的基础,客户端知道他们拥有@3 之前的所有内容,可以使用诸如SELECT * FROM emps WHERE rowversion>3 and rowversion<=new_anchor 之类的查询来获取最新更新。 .

这是一个客户端已经更新@3 的示例场景 - 假设以下交易自:

@3 - committed
@4 - committed
@5 - committed
@6 - in progress - not committed yet
@7 - committed
@8 - in progress - not committed yet
@9 - committed

客户端更新分三个阶段执行:

  1. 向数据库查询合适的 new_anchor .
  2. 执行 SELECT * FROM emps WHERE rowversion>3 and rowversion<=new_anchor .
  3. 传递new_anchor将值(value)连同结果数据返回给客户。

因为带有 rowversion 的行@6 和@8 仍在进行中,new_anchor必须是@5,这样我们的范围查询就不会遗漏任何未提交的更新。现在客户可以确信它拥有直到 @5 的一切。

所以实际问题提炼出来了:new_anchor怎么可能?无需强制即可安全确定SERIALIZABLE或者以其他方式严重损害性能?

正如您可能知道的那样,我从 SQL Server 中借鉴了这个想法,这个问题可以通过 min_active_rowversion() 轻松解决。功能。在上面的场景中这个函数会返回@6,所以你的new_anchor可以安全地min_active_rowversion() - 1 .我有点知道如何使用 active_rowversions 在 Postgres 中实现它表、触发器和 SELECT min(id) FROM active_rowversions , 但这需要 READ UNCOMMITTED隔离,这在 Postgres 中不可用。

如果有任何帮助或想法,我将不胜感激。

最佳答案

事实证明,由于 Postgres 的 System Information Functions,解决方案比最初想象的要简单得多.

  • txid_current() 可用于触发器中以分配记录的 rowversion
  • txid_snapshot_min(txid_current_snapshot()) 可用于获取最小事件事务,其方式与 SQL Server 用户可能使用 min_active_rowversion() 的方式相同。

最好的部分是这些是 64 位的、永久的、不受 vacuum 影响的:

These functions export a 64-bit format that is extended with an "epoch" counter so it will not wrap around during the life of an installation.

Postgres 真的很棒。

关于sql - 在 Postgres 中使用行版本实现增量客户端更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28444599/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com