Skalieren von PostgreSQL-Triggern

14

Wie Postgres Mechanismenwaagen auslöst?

Wir haben eine große PostgreSQL-Installation und versuchen, ein ereignisbasiertes System mithilfe von Protokolltabellen und TRIGGER (s) zu implementieren.

Grundsätzlich möchten wir für jede Tabelle, die für eine UPDATE / INSERT / DELETE-Operation benachrichtigt werden soll, einen TRIGGER erstellen. Sobald dieser Trigger ausgelöst wird, führt er eine Funktion aus, die einfach eine neue Zeile (die das Ereignis codiert) an eine Protokolltabelle anfügt, die wir dann von einem externen Service abfragen.

Bevor wir mit Postgres TRIGGER (s) anfangen, möchten wir wissen, wie sie skaliert werden: Wie viele Trigger können wir in einer einzelnen Postgres-Installation erstellen? Beeinträchtigen sie die Abfrageleistung? Hat das schon mal jemand versucht?

Ugo Matrangolo
quelle
Möglicherweise ist es hilfreich, PgQ zu überprüfen . Es werden C-Trigger zum Registrieren der Datenänderungsereignisse verwendet.
Dezso
Schauen Sie sich listen / notify
a_horse_with_no_name

Antworten:

17

Grundsätzlich möchten wir für jede Tabelle, die für eine UPDATE / INSERT / DELETE-Operation benachrichtigt werden soll, einen TRIGGER erstellen. Sobald dieser Trigger ausgelöst wird, führt er eine Funktion aus, die einfach eine neue Zeile (die das Ereignis codiert) an eine Protokolltabelle anfügt, die wir dann von einem externen Service abfragen.

Das ist eine ziemlich übliche Verwendung für einen Abzug.

Bevor wir mit Postgres TRIGGER (s) anfangen, möchten wir wissen, wie sie skaliert werden: Wie viele Trigger können wir in einer einzelnen Postgres-Installation erstellen?

Wenn Sie sie weiterhin erstellen, ist möglicherweise nicht mehr genügend Speicherplatz vorhanden.

Es gibt keine spezifische Grenze für Trigger.

PostgreSQL-Limits sind auf der About-Seite dokumentiert .

Beeinträchtigen sie die Abfrageleistung?

Dies hängt vom Triggertyp, der Triggersprache und der Funktion des Triggers ab.

Ein einfacher PL / PgSQL- BEFORE ... FOR EACH STATEMENTTrigger, der nichts tut, hat einen Overhead nahe Null.

FOR EACH ROWTrigger haben einen höheren Overhead als FOR EACH STATEMENTTrigger. Die Skalierung mit den betroffenen Zeilenzahlen ist offensichtlich.

AFTERTrigger sind teurer als BEFORETrigger, da sie in die Warteschlange gestellt werden müssen, bis die Anweisung ihre Arbeit beendet und dann ausgeführt wird. Sie werden nicht auf die Festplatte verschüttet, wenn die Warteschlange groß wird (zumindest in 9.4 und darunter, kann sich in Zukunft ändern), sodass große AFTERTriggerwarteschlangen zu einem Überlauf des verfügbaren Speichers führen können, was zum Abbruch der Anweisung führt.

Ein Trigger, der die NEWZeile vor dem Einfügen / Aktualisieren ändert, ist billiger als ein Trigger, der DML ausführt.

Der von Ihnen gewünschte Anwendungsfall FOR EACH STATEMENTbietet eine bessere Leistung mit einer in Bearbeitung befindlichen Verbesserung, die es in PostgreSQL 9.5 schaffen könnte (wenn wir Glück haben), wo Trigger virtuelle OLDund NEWTabellen sehen können. Dies ist in aktuellen PostgreSQL-Versionen nicht möglich, daher müssen Sie FOR EACH ROWstattdessen Trigger verwenden.

Hat das schon mal jemand versucht?

Natürlich. Es ist eine ziemlich übliche Verwendung für Trigger, zusammen mit Auditing, Sanity Checking usw.

Sie werden in aussehen soll LISTENund NOTIFYfür eine gute Möglichkeit , Ihre Arbeitskraft , wenn Änderungen an der Aufgabentabelle aufzuwachen passieren.

Sie tun bereits das Wichtigste, indem Sie vermeiden, über Trigger direkt mit externen Systemen zu kommunizieren. Dies ist in Bezug auf Leistung und Zuverlässigkeit in der Regel problematisch. Oft wird versucht, E-Mails direkt von einem Auslöser aus zu senden, und das sind schlechte Nachrichten.

Craig Ringer
quelle
1

Es ist eine etwas verspätete Antwort, aber es könnte für zukünftige Leser nützlich sein

Heutzutage (in 10,11,12-Versionen) müssen wir dieselben Daten nicht zweimal speichern (in WAL von PG und manuell). Wir können die Postgre Logical Decoding- Mechanik (genau wie die logische Replikation) verwenden, um alle oder einige Änderungen an unseren Daten zu verfolgen (oder diese Ereignisse an eine Warteschlange wie kafka senden, um sie später zu analysieren).

Alexandr Latushkin
quelle