web-dev-qa-db-fra.com

Mise à l'échelle des déclencheurs PostgreSQL

Comment Postgres déclenche les échelles du mécanisme?

Nous avons une grande installation PostgreSQL et nous essayons d'implémenter un système basé sur des événements en utilisant des tables de log et des TRIGGER (s).

Fondamentalement, nous aimerions créer un TRIGGER pour chaque table dont nous voulons être informés pour une opération UPDATE/INSERT/DELETE. Une fois ce déclencheur déclenché, il exécutera une fonction qui ajoutera simplement une nouvelle ligne (codant l'événement) à une table de journal que nous interrogerons ensuite à partir d'un service externe.

Avant de commencer avec Postgres TRIGGER (s), nous aimerions savoir comment ils évoluent: combien de déclencheurs pouvons-nous créer sur une seule installation Postgres? Affectent-ils les performances des requêtes? Quelqu'un at-il déjà essayé cela?

15
Ugo Matrangolo

Fondamentalement, nous aimerions créer un TRIGGER pour chaque table dont nous voulons être informés pour une opération UPDATE/INSERT/DELETE. Une fois ce déclencheur déclenché, il exécutera une fonction qui ajoutera simplement une nouvelle ligne (codant l'événement) à une table de journal que nous interrogerons ensuite à partir d'un service externe.

C'est une utilisation assez standard pour un déclencheur.

Avant de commencer avec Postgres TRIGGER (s), nous aimerions savoir comment ils évoluent: combien de déclencheurs pouvons-nous créer sur une seule installation Postgres?

Si vous continuez à les créer, vous finirez par manquer d'espace disque.

Il n'y a pas de limite spécifique pour les déclencheurs.

Les limites de PostgreSQL sont documentées sur la page à propos .

Affectent-ils les performances des requêtes?

Cela dépend du type de déclencheur, de la langue du déclencheur et de ce que fait le déclencheur.

Un PL/PgSQL simple BEFORE ... FOR EACH STATEMENT le déclencheur qui ne fait rien a une surcharge proche de zéro.

FOR EACH ROW les déclencheurs ont des frais généraux plus élevés que FOR EACH STATEMENT déclenche. Évolutivité, évidemment, avec le nombre de lignes affectées.

Les déclencheurs AFTER sont plus chers que les déclencheurs BEFORE car ils doivent être mis en file d'attente jusqu'à ce que l'instruction termine son travail, puis exécutés. Ils ne sont pas déversés sur le disque si la file d'attente est volumineuse (au moins dans 9.4 et ci-dessous, peut changer à l'avenir) donc d'énormes files d'attente de déclenchement AFTER peuvent entraîner un dépassement de la mémoire disponible, entraînant l'abandon de l'instruction.

Un déclencheur qui modifie la ligne NEW avant l'insertion/la mise à jour est moins cher qu'un déclencheur qui fait du DML.

Le cas d'utilisation spécifique que vous souhaitez fonctionnerait mieux avec une amélioration en cours qui pourrait en faire PostgreSQL 9.5 (si nous sommes chanceux), où FOR EACH STATEMENT les déclencheurs peuvent voir les tables virtuelles OLD et NEW. Ce n'est pas possible dans les versions actuelles de PostgreSQL, vous devez donc utiliser FOR EACH ROW se déclenche à la place.

Quelqu'un at-il déjà essayé cela?

Bien sûr. C'est une utilisation assez standard pour les déclencheurs, ainsi que pour l'audit, la vérification de l'intégrité, etc.

Vous voudrez examiner LISTEN et NOTIFY pour un bon moyen de réveiller votre travailleur lorsque des modifications sont apportées à la table des tâches.

Vous faites déjà la chose la plus importante en évitant de parler aux systèmes externes directement à partir des déclencheurs. Cela a tendance à être problématique pour les performances et la fiabilité. Les gens essaient souvent de faire des choses comme envoyer du courrier directement à partir d'un déclencheur, et c'est une mauvaise nouvelle.

18
Craig Ringer

C'est une réponse légèrement tardive, mais elle pourrait être utile pour les futurs lecteurs

De nos jours (dans les versions 10,11,12), nous n'avons pas besoin de stocker les mêmes données deux fois (dans WAL par PG et manuellement). Nous pouvons utiliser Postgre décodage logique mécanique (identique à la réplication logique) pour suivre tout ou partie des modifications de nos données (ou envoyer ces événements à une file d'attente comme kafka pour analyser plus tard)

1
Alexandr Latushkin