如何从指定点(时间戳或事务ID)查询postgres增量更新?

时间:2015-09-29 05:31:26

标签: postgresql transactions

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

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

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

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

问题是:我不确定事务ID和xmin是否可以可靠地用于检测增量更改(已知的transaction_id溢出/重置问题除外)。

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

1 个答案:

答案 0 :(得分:0)

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

由于您在评论中注意到您正在使用AWS RDS,此时您运气不佳,因为在撰写本文时RDS并未提供任何解码插件而且您已经#39 ; d需要超级用户权限才能安装它们。

您无法使用xmin和xmax进行完整的增量复制,因为您无法在PostgreSQL中执行脏读操作,因此您无法查看元组是否为DELETE d。要使用交易ID,您需要阻止VACUUM删除" dead"行,即当前事务仍无需正确执行的行。您还需要能够进行脏读。这些都没有PostgreSQL中的简单解决方案。

如果您有仅插入表(或者您执行插入和更新,从不删除,也从不更改行的主键),那么您可以使用事务xmin。您必须通过检查pg_database.datfrozenxidpg_class.relfrozenxid来了解感兴趣的关系,从而处理transaction-id wraparound。有关详细信息,请参阅代码中的源代码和注释。如果您从不删除条目,VACUUM并且缺少脏读不是问题,因为您不需要看到"消失"行。

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

如果您可以完全禁止删除和主键更改,则可以使用xmin查找已更改的行,只要您注意确保没有delete运行或任何{{1改变update s。

的s