web-dev-qa-db-ja.com

PostgreSQL TRIGGERのスケーリング

Postgresがメカニズムスケールをトリガーする方法

大規模なPostgreSQLインストールがあり、ログテーブルとTRIGGERを使用してイベントベースのシステムを実装しようとしています。

基本的に、UPDATE/INSERT/DELETE操作の通知を受け取るテーブルごとにTRIGGERを作成します。このトリガーが起動すると、新しい行(イベントをエンコード)をログテーブルに追加する関数を実行します。このログテーブルを外部サービスからポーリングします。

すべてのPostgres TRIGGERに入る前に、それらがどのようにスケールするかを知りたいと思います。単一のPostgresインストールで何個のトリガーを作成できますか?クエリのパフォーマンスに影響しますか?これまでに誰かがこれを試しましたか?

15
Ugo Matrangolo

基本的に、UPDATE/INSERT/DELETE操作の通知を受け取るテーブルごとにTRIGGERを作成します。このトリガーが起動すると、新しい行(イベントをエンコード)をログテーブルに追加する関数を実行します。このログテーブルを外部サービスからポーリングします。

これは、トリガーのかなり標準的な使用法です。

PostgresのTRIGGERをすべて使用する前に、それらがどのようにスケールするかを知りたいと思います。単一のPostgresインストールで何個のトリガーを作成できますか?

それらを作成し続けると、最終的にはディスク領域が不足します。

トリガーに特定の制限はありません。

PostgreSQLの制限は文書化されています 概要ページ

クエリのパフォーマンスに影響しますか?

トリガーのタイプ、トリガー言語、およびトリガーの機能によって異なります。

何もしない単純なPL/PgSQL BEFORE ... FOR EACH STATEMENTトリガーのオーバーヘッドはほぼゼロです。

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を調べてください。

トリガーから直接外部システムと通信しないようにすることで、すでに最も重要なことを実行しています。これは、パフォーマンスと信頼性にとって問題になる傾向があります。トリガーから直接メールを送信するなど、人々はよくしようとしますが、それは悪いニュースです。

18
Craig Ringer

少し遅れた答えですが、将来の読者にとって役立つかもしれません

現在、10、11、12バージョンでは、同じデータを2回(PGによるWALと手動で)保存する必要はありません。 Postgre Logical Decoding mechanics(論理レプリケーションと同じ)を使用して、データのすべてまたは一部の変更を追跡できます(またはこれらのイベントをkafkaなどのキューに送信して分析します後)

1