Postgres LISTEN / NOTIFY - 低延迟,实时?

时间:2015-10-02 19:12:07

标签: postgresql real-time notify listen low-latency

我计划使用postgres LISTEN / NOTIFY 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来接收这些通知。

我想知道的是事务提交发生的确切时间(记录可以读取)到微秒级

我知道NOTIFY(pg_notify)实际上在提交事务后立即发送通知,但我无法弄清楚如何找出它发生的确切时间。我在NOTIFY中的时钟时间戳值不是实际的事务提交时间。

我想我收听通知的时间将接近事务提交时间,但我不确定它的接近程度。首先,在我的代码中进行民意调查时会有一段时间(但是很小),其次,我不确定NOTIFY / LISTEN通信本身之间是否存在任何延迟。

有什么想法吗?

UPDATE(问题的完整描述):我们让读者使用“检查点”时间批量选择行,其中每个批次获取上一批次中最后一个时间戳之后的行,我们缺少行。 (原因:时间戳值基于INSERT发生的时间(00.00.00)。在重负载时,如果事务需要更长的时间,它会被插入,比如10秒后(00.00.10),读者将错过这一行(row1)如果它在那10秒内读取并找到一个行,其行的INSERT时间晚于(00.00.05)而不是row1。问题的完整描述类似于本博客中写的那个。{{3 }})

2 个答案:

答案 0 :(得分:2)

  

我想知道的是事务提交发生的确切时间(记录可以读取)到微秒级

当然,PostgreSQL 9.5只是以支持提交时间戳的形式添加了它。见commit timestamps。请注意,您必须启用track_commit_timestamp才能使用此功能,并且有关提交时间戳的信息不会永久保留,因此相当旧的行只会获得null结果。

您可以在交易期间的任何时候获取带有txid_current()的交易ID。也许以insert ... returning ...为例。然后,您可以在提交后在后续查询中查找提交时间戳。

对于旧版本,您应该在clock_timestamp子句中包含insert ... returning ...。它将是插入记录的时间,而不是提交时间,但它确实是最接近的记录。

  

我想我收听通知的时间将接近事务提交时间,但我不确定它的接近程度。

"相当&#34 ;.它将取决于网络延迟,CPU调度滞后等。它肯定不会是微秒准确的。

例如,在Windows上,它最好精确到毫秒,但默认情况下它会精确到最接近的15毫秒计时器滴答。

  

首先,在我的代码中进行民意调查时会有一段时间(无论多么小)

不要投票。 select()套接字,这样您就可以立即唤醒那里的数据。在Linux上,您最好使用epoll()系统调用。

  

第二,我不确定NOTIFY / LISTEN通讯本身之间是否存在任何延迟。

有些,是的,因为事务提交需要时间。因此,在您发出NOTIFY和将事件发送给听众之间会有一些非零时间。

答案 1 :(得分:1)

now()将始终小于提交事务并且对读者可见的实际时间(除非您将脏读作为隔离级别)。

更好的方法(没有竞争条件的方法)是调用pg_notify()并在事务结束后立即使用clock_timestamp()(仅当事务提交时)。