扩展 PostgreSQL 触发器

Ugo*_*olo 17 postgresql performance scalability query-performance

Postgres 如何触发机制规模?

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

基本上,我们希望为每个我们希望收到更新/插入/删除操作通知的表创建一个 TRIGGER。一旦触发此触发器,它将执行一个函数,该函数将简单地将一个新行(对事件进行编码)附加到一个日志表中,然后我们将从外部服务轮询该日志表。

在全面使用 Postgres TRIGGER(s) 之前,我们想知道它们是如何扩展的:我们可以在单个 Postgres 安装上创建多少个触发器?它们会影响查询性能吗?有没有人试过这个?

Cra*_*ger 19

基本上,我们希望为每个我们希望收到更新/插入/删除操作通知的表创建一个 TRIGGER。一旦触发此触发器,它将执行一个函数,该函数将简单地将一个新行(对事件进行编码)附加到一个日志表中,然后我们将从外部服务轮询该日志表。

这是触发器的一个非常标准的用法。

在全面使用 Postgres TRIGGER(s) 之前,我们想知道它们是如何扩展的:我们可以在单个 Postgres 安装上创建多少个触发器?

如果您继续创建它们,最终您将耗尽磁盘空间。

触发器没有特定限制。

PostgreSQL 限制记录在关于页面上

它们会影响查询性能吗?

这取决于触发器类型、触发器语言以及触发器的作用。

一个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寻找一种唤醒工作人员的好方法。

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