Skalowanie wyzwalaczy PostgreSQL

14

W jaki sposób Postgres wyzwala skalę mechanizmu?

Mamy dużą instalację PostgreSQL i staramy się zaimplementować system oparty na zdarzeniach, używając tabel dzienników i wyzwalaczy.

Zasadniczo chcielibyśmy utworzyć TRIGGER dla każdej tabeli, dla której chcemy być powiadamiani o operacji UPDATE / INSERT / DELETE. Gdy ten wyzwalacz zostanie uruchomiony, wykona funkcję, która po prostu doda nowy wiersz (kodowanie zdarzenia) do tabeli dziennika, którą następnie sondujemy z usługi zewnętrznej.

Przed przystąpieniem do all-inu z wyzwalaczami Postgres chcielibyśmy wiedzieć, jak się skalują: ile wyzwalaczy możemy stworzyć w ramach jednej instalacji Postgres? Czy wpływają na wydajność zapytań? Czy ktoś wcześniej tego próbował?

Ugo Matrangolo
źródło
Przydatne może być sprawdzenie PgQ , używa on wyzwalaczy C do rejestrowania zdarzeń modyfikacji danych.
dezso,
Spójrz na
Listen

Odpowiedzi:

17

Zasadniczo chcielibyśmy utworzyć TRIGGER dla każdej tabeli, dla której chcemy być powiadamiani o operacji UPDATE / INSERT / DELETE. Gdy ten wyzwalacz zostanie uruchomiony, wykona funkcję, która po prostu doda nowy wiersz (kodowanie zdarzenia) do tabeli dziennika, którą następnie sondujemy z usługi zewnętrznej.

To dość standardowe użycie wyzwalacza.

Przed przystąpieniem do all-inu z wyzwalaczami Postgres chcielibyśmy wiedzieć, jak się skalują: ile wyzwalaczy możemy stworzyć w ramach jednej instalacji Postgres?

Jeśli będziesz je dalej tworzyć, w końcu zabraknie Ci miejsca na dysku.

Nie ma określonego limitu wyzwalaczy.

Limity PostgreSQL są udokumentowane na stronie about .

Czy wpływają na wydajność zapytań?

Zależy to od typu wyzwalacza, języka wyzwalacza i jego działania.

Prosty BEFORE ... FOR EACH STATEMENTwyzwalacz PL / PgSQL, który nic nie robi, ma narzut bliski zeru.

FOR EACH ROWwyzwalacze mają wyższy narzut niż FOR EACH STATEMENTwyzwalacze. Skalowanie, oczywiście, z liczonymi wierszami.

AFTERwyzwalacze są droższe niż BEFOREwyzwalacze, ponieważ muszą być ustawione w kolejce, dopóki instrukcja nie zakończy wykonywania swojej pracy, a następnie wykonane. Nie są one rozlewane na dysk, jeśli kolejka się powiększy (przynajmniej w wersji 9.4 i niższej może się zmienić w przyszłości), więc ogromne AFTERkolejki wyzwalające mogą spowodować przepełnienie dostępnej pamięci, co powoduje przerwanie instrukcji.

Wyzwalacz, który modyfikuje NEWwiersz przed wstawieniem / aktualizacją, jest tańszy niż wyzwalacz, który wykonuje DML.

Konkretny przypadek użycia, który chcesz, działałby lepiej dzięki ulepszeniu w toku, które może przekształcić go w PostgreSQL 9.5 (jeśli mamy szczęście), gdzie FOR EACH STATEMENTwyzwalacze mogą zobaczyć wirtualny OLDi NEWtabele. Nie jest to możliwe w obecnych wersjach PostgreSQL, dlatego FOR EACH ROWzamiast tego należy użyć wyzwalaczy.

Czy ktoś wcześniej tego próbował?

Oczywiście. Jest to dość standardowe zastosowanie do wyzwalaczy, wraz z audytem, ​​sprawdzaniem czystości itp.

Będziesz chciał przyjrzeć się LISTENi NOTIFYznaleźć dobry sposób na obudzenie pracownika, gdy nastąpią zmiany w tabeli zadań.

Już robisz najważniejszą rzecz, unikając rozmowy z systemami zewnętrznymi bezpośrednio z wyzwalaczy. Jest to zwykle problematyczne pod względem wydajności i niezawodności. Ludzie często próbują robić rzeczy takie jak wysyłanie poczty bezpośrednio z wyzwalacza, a to złe wieści.

Craig Ringer
źródło
1

To nieco spóźniona odpowiedź, ale może być przydatna dla przyszłych czytelników

Teraz dni (w wersjach 10,11,12) nie musimy przechowywać tych samych danych dwa razy (w WAL przez PG i ręcznie). Możemy użyć mechaniki Postgre Logical Decoding (tak samo jak replikacja logiczna), aby śledzić wszystkie lub niektóre zmiany naszych danych (lub wysłać te zdarzenia do jakiejś kolejki, takiej jak kafka, aby przeanalizować później)

Alexandr Latushkin
źródło