Postgresql 如何查询postgres自指定点(时间戳或事务id)以来的增量更新?

Postgresql 如何查询postgres自指定点(时间戳或事务id)以来的增量更新?,postgresql,transactions,Postgresql,Transactions,我希望能够找到postgresql表的增量更改 我知道我可以使用timestamp方法:添加一个timestamp列,当一行被更新时,我可以用它保存一个timestamp,然后可以查询在指定的timestamp之后更改的行。出于某种原因,数据库触发器不是我的选项,如果不使用数据库触发器,我必须在web服务器上生成时间戳,这需要使用NTP来控制服务器之间的时间容差,而这也不是我的选项,因为我无法控制服务器 因此,我转向另一种解决方案:选择在指定事务id之后修改的行。在Postgres中,txid_

我希望能够找到postgresql表的增量更改

我知道我可以使用timestamp方法:添加一个timestamp列,当一行被更新时,我可以用它保存一个timestamp,然后可以查询在指定的timestamp之后更改的行。出于某种原因,数据库触发器不是我的选项,如果不使用数据库触发器,我必须在web服务器上生成时间戳,这需要使用NTP来控制服务器之间的时间容差,而这也不是我的选项,因为我无法控制服务器

因此,我转向另一种解决方案:选择在指定事务id之后修改的行。在Postgres中,txid_current()可以返回当前事务id,我可以通过sql“select*from table_name where xmin>{transaction_id}”获得增量更新

经过一些简单的测试,我发现它是有效的。一个已知的问题是,事务id将随着时间的推移而增长,有一天需要postgres重置,但我正在考虑在事务id接近最大值时临时禁用增量更新功能,并在重置完成后重新启用它

问题是:我不确定是否可以可靠地使用事务id和xmin来检测增量更改(除了已知的事务id溢出/重置问题)


感谢您对增量更新的任何建议。也许还有其他方法可以查询增量更新。

您真正想要的是PostgreSQL 9.4的支持,它允许您从服务器提取更改流。要使用它,您需要一个逻辑解码插件,将服务器上的更改流转换为您的应用程序可以使用的内容。有一些正在开发中,但还为时过早

因为你在评论中提到你正在使用AWS RDS,所以现在你运气不好,因为在撰写本文时RDS不提供任何解码插件,你需要超级用户权限才能安装它们

您不能使用xmin和xmax进行完整的增量复制,因为您不能在PostgreSQL中执行脏读取,所以您无法查看元组是否已被删除。要使用事务ID,您需要防止
VACUUM
删除“死”行,即当前事务仍不需要正确执行的行。你还需要能够做肮脏的阅读。这两种方法在PostgreSQL中都没有简单的解决方案

如果您只有insert only表(或者您进行插入和更新,从不删除,也从不更改行的主键),那么您可以使用事务xmin。您必须通过检查
pg_database.datfrozenxid
pg_class.relfrozenxid
来处理兴趣关系。有关详细信息,请参阅代码中的源代码和注释<代码>真空如果您从不删除条目,那么缺少脏读也不是问题,因为您不需要看到“消失”的行

如果可能,使用9.4+中的逻辑解码。对于旧版本,如果需要完整复制,则需要使用触发器累积更改队列


如果您可以完全禁止删除和主键更改,那么您可以使用
xmin
查找更改的行,只要您注意确保没有运行
delete
s,或任何
update
s更改
主键
s。因为您无法“查看”,所以不能仅使用txid来获得增量更改这样就删除了行。正如我在下面回答中的评论,我的记录不会被删除。还有其他原因吗?如果所有表都有一个串行(代理)键,那么可以将其用作高水位线。否则,您可以向表中添加序列号。(注意:显然不适用于更新)逻辑解码对我的应用程序来说很难。PostgreSQL手册涵盖了真空。逻辑解码将是最快和最有效的方式来做你想做的事情,但通用输出插件还没有真正成熟和广泛可用,所以它并不理想。如果您完全只进行更新和插入,那么您可能不需要单独使用xmin,但是您必须非常小心地处理txid wrapparound,并确保检查数据库xid。如果你打算这样做,那么你应该阅读源代码和开发人员文档。你直接摆弄数据库的内部结构。@Michael,因为XID是在txn开始时分配的,当它第一次写入时。TXN不保证按xid升序提交。我认为可以在当前tx的可视快照上使用postgres的信息,但如果没有大量的验证,我不会打赌。更为复杂的是,提交的WAL记录不能保证以与提交在共享内存中可见的顺序相同的顺序写入,因此如果不小心,可能会出现崩溃和恢复的顺序问题。我们真正需要的是某种方法来构造一个可以假脱机差异更改集的插槽。目前,您只能读取增量更改蒸汽。但是在你考虑DDL之前,处理差分变化集是非常困难的;我一点也不确定我们会怎么做。同样要清楚的是,您永远无法正确地使用xmin进行同步。由于提交之间的并发性,它似乎在大多数情况下都能工作,同时会引入一些微妙的累积数据错误。简单化的测试用例会起作用,然后它会在负载下投入生产。所以不要那样做。