Postgresがメカニズムスケールをトリガーする方法
大規模なPostgreSQLインストールがあり、ログテーブルとTRIGGERを使用してイベントベースのシステムを実装しようとしています。
基本的に、UPDATE/INSERT/DELETE操作の通知を受け取るテーブルごとにTRIGGERを作成します。このトリガーが起動すると、新しい行(イベントをエンコード)をログテーブルに追加する関数を実行します。このログテーブルを外部サービスからポーリングします。
すべてのPostgres TRIGGERに入る前に、それらがどのようにスケールするかを知りたいと思います。単一のPostgresインストールで何個のトリガーを作成できますか?クエリのパフォーマンスに影響しますか?これまでに誰かがこれを試しましたか?
基本的に、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
トリガーは仮想OLD
とNEW
テーブル。これは現在のPostgreSQLバージョンでは不可能であるため、代わりにFOR EACH ROW
トリガーを使用する必要があります。
これまでに誰かがこれを試しましたか?
もちろん。これは、監査、健全性チェックなどとともに、トリガーのかなり標準的な用途です。
タスクテーブルが変更されたときにワーカーをウェイクアップするための適切な方法については、LISTEN
とNOTIFY
を調べてください。
トリガーから直接外部システムと通信しないようにすることで、すでに最も重要なことを実行しています。これは、パフォーマンスと信頼性にとって問題になる傾向があります。トリガーから直接メールを送信するなど、人々はよくしようとしますが、それは悪いニュースです。
少し遅れた答えですが、将来の読者にとって役立つかもしれません
現在、10、11、12バージョンでは、同じデータを2回(PGによるWALと手動で)保存する必要はありません。 Postgre Logical Decoding mechanics(論理レプリケーションと同じ)を使用して、データのすべてまたは一部の変更を追跡できます(またはこれらのイベントをkafkaなどのキューに送信して分析します後)