タイトルだけで完結する内容ですが、ハマった記念に残しておきます
やったこと
AWS Aurora PostgreSQLにFunction, Triggerを作成して、「特定のテーブルAのデータが更新されたら、テーブルBにデータを登録/更新する」ようにした
テーブルAにデータ登録、更新、削除どれを行ってもテーブルBにデータが連携されない
根本原因はDBパラメータグループの設定値session_replication_roleがreplica
になっていることでした
この値をorigin
に変更すると、正常にTriggerが発火した
原因調査
ENABLE REPLICA TRIGGER
たまたまPostgreSQL 9.5.4 のサイトに辿り着き、Triggerの有効/無効を設定する方法は「ALTER TABLE …. ENABLE TRIGGER …」だけではなく、「ALTER TABLE …. ENABLE REPLICA TRIGGER …」も存在することを知りました
ALTER TABLE test_schema.table_a ENABLE REPLICA TRIGGER table_a_trigger
これを実行するとtriggerが正常に発火し、意図した挙動になったことから、原因はREPLICA
周りの設定であることが推測できました
TRIGGERとREPLICA TRIGGERの違い
ChatGPTが教えてくれた
ENABLE TRIGGER: このコマンドは、トリガーをデフォルトのトリガーモード(通常のトリガーモード)で有効にします。
トリガーモード:
BEFORE: トリガーが対象の操作(INSERT, UPDATE, DELETEなど)が実行される前に発火します。
AFTER: トリガーが対象の操作が完了した後に発火します。
ENABLE REPLICA TRIGGER: このコマンドは、トリガーをレプリカ(複製)ノードでのみ発火するモードで有効にします。
レプリカ(複製)ノード:
レプリカノードは、主(マスター)ノードからのデータの複製を持つスタンバイノードやレプリカノードを指します。
Auroraのクラスターでは、レプリカノードが自動的に作成される場合があります。
適用シナリオ
ENABLE TRIGGER:
主に、トリガーが主ノードとレプリカノードの両方で発火する場合や、主にデータの整合性を保つために使用されます。
ENABLE REPLICA TRIGGER:
レプリカノードでのみトリガーを発火させたい場合や、レプリカノードでのリソース使用量を削減したい場合に使用されます。
つまり主ノードとレプリカノードのtirggerの挙動を変えるための設定が可能なんですね
session_replication_role
replica triggerについて調べていると、triggerを一時的に無効にしたい場合にsession_replication_roleの値をイジる方法がいくつかヒットしました
PostgreSQLで一時的にtriggerを全て無効する方法
Studio ODIN – blog風小ネタ集 > PostgreSQL で、一時的に全てのトリガーを無効にする
SET session_replication_role = replica;
defaultではsession_replication_roleはorigin
になっているところをreplica
に変える方法
どうやら裏技的に使われている様子
なので僕がいじっているPostgresのsession_replication_roleを値を確認しました
SELECT name, setting, boot_val, reset_val, unit
FROM pg_settings
where name='session_replication_role';
裏技が使われてました
DBを管理してる方が一時的に全てのtriggerを無効にするために設定していたらしく、
結局はDBパラメータグループの値を元に戻すことでTriggerが正常に動く状態になり、めでたし!
まとめ
PostgreSQLのレプリケーションについて意識する良い機会でした
この本読んで勉強しよう!
[改訂新版]内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)