从postgresql中的表流式传输数据的有效方法?
问题描述:
我有一个日志表,仅附加一些数据,我希望将它们传回客户端。从postgresql中的表流式传输数据的有效方法?
存在一种方法来从它流数据只使用PG没有轮询?
这样我就可以得到:
1. Inv.Add 1, T=10
.. some seconds after, the server push?
2. Inv.Add 2, T=15
答
添加这就要求NOTIFY
触发,然后让你的客户listen
到该通道。
Listen和Notify有一些巨大的注意事项,但他们确实在做你想做的事情。例如,对谁可以发送通知没有安全权限检查,因此不要依赖任何有效负载。
我的做法是:
- LISTEN(第一,以防止竞争条件)
- 读取表。存储最新的时间戳,序列号或其他递增值
- 当您收到通知时,查询表中所有后面的行。永远重复。
您可以再次通过通知发送行数据,但任何人都可以发送您的应用程序行数据,如果他们可以连接到数据库,这有点危险。
答
PostgreSQL没有任何方法来启动任何操作。所有活动必须由外部事件触发。
您可以在表上添加一个plperlu触发器,以便从插入的行的值中对输出进行格式化,并将它们附加到给定的日志文件中。
CREATE OR REPLACE FUNCTION tf_log_to_file() RETURNS trigger AS
$BODY$
use strict;
use Time::HiRes qw(time);
use POSIX qw(strftime);
my $t = time;
my $date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000;
my $contents = $date . ' Inv.Add ' . $_TD->{new}{yourcolname};
my $file = "/var/log/mylog.log";
open(my $out, '>>', $file) or die "Unable to open or create file $file: $!";
print $out decode_bytea($contents);
close($out);
$BODY$ LANGUAGE plperlu VOLATILE SECURITY DEFINER;
CREATE TRIGGER t_log_to_file AFTER INSERT ON yourtable
FOR EACH ROW EXECUTE PROCEDURE tf_log_to_file();