我计划使用postgres侦听/通知aproach来获取表中记录的插入时间(实际事务提交时间)。为了实现这一点,我计划做以下工作。我在插入时间发出通知,如下所示。
BEGIN;
INSERT INTO table_name(id, ...) values (id,....);
select pg_notify('test_channel', 'id - ' || id || ' trans start time - ' || now() || ' notify start time - ' || clock_timestamp());
END;然后,我计划使用https://pythonhosted.org/psycopg2/advanced.html#asynchronous-notifications接收这些通知。
我想知道的是事务提交发生的确切时间(记录可以读取),直到微秒。
我知道notification (Pg_notify)实际上是在事务提交后立即发送通知,但我不知道如何找出它发生的确切时间。时钟时间戳值我在通知中,不是指事务提交时间。
我想我听通知的时间将接近事务提交时间,但我不确定它有多近。首先,我的代码中的轮询(无论多小)之间有一段时间,第二,我不确定通知/侦听通信本身是否有任何滞后。
有什么想法吗?
UPDATE(问题的完整描述):我们有一个读取器使用“检查点”时间在批中选择行,其中每个批处理在上一批中的最后一个时间戳之后获得行,并且缺少行。(原因:时间戳值基于发生的时间插入(00.00.00)。在重负载时,如果事务花费更长的时间,则会在10秒后(00.00.10)插入--比方说,如果在这10秒内读取并找到比row1更晚的插入时间(00.00.05),读取器将错过该行(Row1)。对问题的完整描述类似于在这个博客中所写的描述。http://blog.thefourthparty.com/stopping-time-in-postgresql/)
发布于 2015-10-03 10:31:55
我想知道的是事务提交发生的确切时间(记录可以读取),直到微秒。
轻松地,PostgreSQL 9.5只是以支持提交时间戳的形式添加了这个内容。见提交时间戳。请注意,您必须启用track_commit_timestamp才能使用它,并且提交时间戳的信息不会永远保存,因此相当老的行只会得到一个空结果。
您可以在事务过程中的任意点使用txid_current()获取事务ID。例如,可能使用insert ... returning ...。然后,您可以在提交之后的后续查询中查找提交时间戳。
对于旧版本,只需在clock_timestamp子句中包含insert ... returning ...。现在是插入记录的时间,而不是提交时间,但这确实是最接近的时间。
我想我听通知的时间将接近事务提交时间,但我不确定它有多近。
“公平”。它将取决于网络延迟,CPU调度滞后等,它肯定不会是微秒精确.
例如,在Windows上,它最多能精确到毫秒,但默认情况下,它将精确到最近的15毫秒计时器滴答。
首先,在我的代码中有一段时间在听(不管它多小)之间的轮询。
别投票。select()这个套接字,这样你就会在有数据可读的时候醒来。在Linux上,您最好使用epoll()系统调用来实现这一点。
其次,我不确定通知/侦听通信本身是否有任何延迟。
有些,是的,因为事务提交需要时间。因此,在发出NOTIFY时和事件被发送到侦听器之间有一些非零的时间。
发布于 2015-10-02 20:28:13
现在()总是比实际的时间更短,此时事务对读者来说是可执行和可见的(除非您将脏读作为隔离级别)。
一种更好的方法(没有竞争条件的方法)是在事务结束后调用pg_notify()并使用clock_timestamp() (并且只有当事务提交时才使用)。
https://stackoverflow.com/questions/32914252
复制相似问题