扩展PostgreSQL触发器


14

Postgres如何触发机制扩展?

我们有大型的PostgreSQL安装,并且我们正在尝试使用日志表和TRIGGER来实现基于事件的系统。

基本上,我们想为要通知UPDATE / INSERT / DELETE操作的每个表创建一个TRIGGER。触发该触发器后,它将执行一个函数,该函数将简单地将新行(对事件进行编码)追加到日志表中,然后我们将从外部服务中进行轮询。

在开始使用Postgres TRIGGER之前,我们想知道它们如何扩展:在单个Postgres安装中可以创建多少个触发器?它们会影响查询性能吗?之前有人尝试过吗?


您可能会发现检查PgQ很有用,它使用C触发器来注册数据修改事件。
dezso 2015年

看一下监听/通知,您可能根本不需要触发器:postgresql.org/docs/current/static/sql-listen.html
a_horse_with_no_name 2015年

Answers:


17

基本上,我们想为要通知UPDATE / INSERT / DELETE操作的每个表创建一个TRIGGER。触发该触发器后,它将执行一个函数,该函数将简单地将新行(对事件进行编码)追加到日志表中,然后我们将从外部服务中进行轮询。

这是触发器的标准用法。

在开始使用Postgres TRIGGER之前,我们想知道它们如何扩展:在单个Postgres安装中可以创建多少个触发器?

如果继续创建它们,最终将用完磁盘空间。

触发器没有具体限制。

PostgreSQL限制记录在About页面上

它们会影响查询性能吗?

这取决于触发器的类型,触发器的语言以及触发器的功能。

一个BEFORE ... FOR EACH STATEMENT不执行任何操作的简单PL / PgSQL 触发器的开销几乎为零。

FOR EACH ROW触发器比FOR EACH STATEMENT触发器具有更高的开销。显然,随着受影响的行数进行缩放。

AFTER触发器比BEFORE触发器更昂贵,因为触发器必须排队直到语句完成其工作,然后执行。如果队列变大(至少在9.4及以下版本,可能会在将来更改),它们不会溢出到磁盘上,因此庞大的AFTER触发器队列可能导致可用内存溢出,从而导致语句中止。

NEW在插入/更新之前修改行的触发器比执行DML的触发器便宜。

您想要的特定用例将通过正在进行的增强而更好地执行,该增强可能会使其纳入PostgreSQL 9.5(如果幸运的话),其中FOR EACH STATEMENT触发器可以看到虚拟OLDNEW表。在当前的PostgreSQL版本中这是不可能的,因此您必须使用FOR EACH ROW触发器。

之前有人尝试过吗?

当然。这是触发器,审计,健全性检查等的标准用法。

当任务表发生更改时,您需要研究一下LISTENNOTIFY找到一种唤醒工作人员的好方法。

通过避免直接从触发器与外部系统对话,您已经在做最重要的事情。这对于性能和可靠性而言往往是有问题的。人们经常尝试做一些事情,例如直接从触发器发送邮件,这是个坏消息。


1

这是一个迟来的答案,但对将来的读者可能有用

现在,几天(在10、11、12版本中)我们不需要两次存储相同的数据(在PG中通过WAL手动存储)。我们可以使用Postgre 逻辑解码机制(与逻辑复制相同)来跟踪数据的全部或部分更改(或将这些事件发送到类似kafka的队列中以供以后分析)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.