bsi*_*nau 8 postgresql timestamp
我有数据拉取功能,可以在 5 秒内根据modified_timestamp列从 Postgres 表中抓取所有数据。它的工作方式如下:
SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
其中modified_timestamp使用触发器更新(在任何行更新modified_timestamp变为 之后CURRENT_TIMESTAMP
)。它工作正常,直到我注意到CURRENT_TIMESTAMP
Postgres 实际上是事务开始时间戳并且一些更新丢失了。他们为什么会迷路?这很简单 - 在我执行查询时,SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
一些更改已经发生,但modified_timestamp在更新_some_persisted_timestamp之前,因为事务仍在进行中。
当更新对其他事务可见(换句话说,事务提交时间戳)而不是 CURRENT_TIMESTAMP 或 clock_timestamp()时,可以通过在步骤 2 中 分配时间戳来轻松解决此问题。
我阅读了文档,但没有发现与事务提交时间戳相关的任何内容。你能不能给点建议?
顺便说一句,我知道逻辑解码,我知道这种机制在理论上更适合我的需求,但有一些实际问题不允许我使用它。
当更新对其他事务可见(换句话说,事务提交时间戳)而不是 CURRENT_TIMESTAMP 或 clock_timestamp() 时,可以通过在步骤 2 中分配时间戳来轻松解决此问题。
这在逻辑上是不可能的。Postgres在它最终提交以使其可见之前写入新的行版本。它需要预言能力来编写在编写时未知的未来时间戳。
但是,您可以从不同的来源获取提交时间戳:从 Postgres 9.5 开始,有一个 GUC 设置track_commit_timestamp
来开始全局记录提交时间戳。
然后您可以使用实用程序函数获取提交时间戳pg_xact_commit_timestamp(xid)
。您的查询可能如下所示:
SELECT * FROM my_table t
WHERE pg_xact_commit_timestamp(t.xmin) > _some_persisted_timestamp;
Run Code Online (Sandbox Code Playgroud)
请注意,提交时间戳不会永远保留。在 20 亿笔交易(2^31)之后,交易 ID 被“冻结”。这不会立即删除它,但是在 40 亿次交易之后,这些信息肯定会消失。这是大量的事务,只有非常繁忙的数据库才能在一生中消耗这么多。但是编程错误可能比预期的更快地烧毁交易编号......
您的第 2 步和第 3 步交易头寸,您记录提交时间戳而不是CURRENT_TIMESTAMP
- 或xmin
从任何新更新的行中再次派生提交时间戳pg_xact_commit_timestamp()
。
更多的:
关于xmin
:
但我不完全确定我理解你的任务。也许您需要一个排队工具或像这里讨论的那样逐行处理:
归档时间: |
|
查看次数: |
6037 次 |
最近记录: |