【実務・中級編】 イベントトリガー – PostgreSQL

「PostgreSQLのイベントトリガー」を使いこなして、DBの「治安」を守る技術

やあ。データベースの運用、お疲れ様。
今日はちょっとマニアックだけど、知っておくと「ここぞという時」にめちゃくちゃ頼りになるイベントトリガー(Event Trigger)の話をしようと思う。

普通のトリガー(テーブルのINSERT/UPDATE/DELETEに反応するやつ)はみんなよく使うよね。でも、PostgreSQLにはDDL(データ定義言語)——つまり`CREATE`とか`ALTER`とか`DROP`が実行された瞬間に反応する、ちょっと特殊な「イベントトリガー」っていう機能があるんだ。

これ、ぶっちゃけ普段使いはしない。でも、大規模なプロジェクトや、開発者が大勢いる環境で「事故」を防ぐための最後の砦として、これほど心強い機能はないんだよ。

—

イベントトリガーって何者?

簡単に言うと、「データベースの構造が変わったその瞬間に、何か別の処理を割り込ませる仕組み」のことだ。

通常のトリガーが「行(データ)」を監視しているのに対し、イベントトリガーは「データベースの器そのもの」を監視している。だから、誰かが間違えて本番環境で`DROP TABLE`を叩こうとしたとき、それを検知して処理を止めるなんていう「門番」のような使い方ができるんだ。

具体的にどんなことができるの?

実務でよくあるユースケースをいくつか挙げてみるね。

1. DDL実行のログ取り: 「いつ」「誰が」「何を」したのか、監査ログとして残す。
2. DDLの禁止: 特定のテーブルに対する`DROP`を禁止して、誤操作を防ぐ。
3. 自動的な権限付与: 新しいテーブルが作られたら、自動的に特定のロールに読み取り権限を付与する。

特に3番目は便利だよね。開発者が新しいテーブルを作るたびに、手作業で`GRANT`文を流す必要がなくなるわけだから。

—

実践:テーブルのDROPを阻止する「門番」を作ってみよう

じゃあ、実際にコードを見てみようか。まずは「DROP TABLEを禁止する」という、運用現場でよくある要望を叶えるスクリプトだ。

— 1. イベントトリガーから呼ばれる関数を作る
CREATE OR REPLACE FUNCTION prevent_drop_table()
RETURNS event_trigger AS $$
BEGIN
RAISE EXCEPTION ‘おいおい、本番環境でDROP TABLEは禁止だよ!’;
END;
$$ LANGUAGE plpgsql;

— 2. DDLの終了直前にトリガーを発火させる
CREATE EVENT TRIGGER trg_prevent_drop ON ddl_command_start
WHEN TAG IN (‘DROP TABLE’)
EXECUTE FUNCTION prevent_drop_table();

これだけで、誰かが`DROP TABLE users;`と打った瞬間にエラーが返ってきて実行が阻止される。どうだい、シンプルだろう?

知っておくべき注意点

便利そうに見えるだろ? でも、イベントトリガーを扱うときはいくつか注意点がある。現場でハマらないために覚えておいてほしい。

  • 「トランザクション」の壁: イベントトリガーは、DDLと同じトランザクション内で動く。だから、もしトリガー内で重い処理をしたり、エラーを起こしたりすると、当然DDLそのものが失敗する。運用を止めてしまうリスクがあるから、処理は極力軽くしておくのが鉄則だ。
  • サポートされているコマンドは限定的: 全てのDDLがトリガー対象になるわけじゃない。`CREATE`, `ALTER`, `DROP`, `COMMENT`, `GRANT`, `REVOKE`あたりがメインだね。マニュアルの「イベントトリガーがサポートするコマンド」の項目には一度目を通しておくといい。
  • デバッグが少し面倒: 失敗した時の挙動がトリガーのせいで追いにくくなることがある。開発環境でしっかりテストしてから投入するのが大前提だ。

最後に:エンジニアとしての心得

イベントトリガーは「魔法の杖」じゃない。あくまで、運用を自動化し、ヒューマンエラーという名の「悲劇」を未然に防ぐための補助ツールだ。

「とりあえず何でもイベントトリガーで自動化しとけば楽だよね」なんて考えていると、後から入ってきたメンバーが「なぜかテーブルが削除できない!」とパニックになる原因を作ってしまうこともある。

「仕組みで管理する」ことと「属人化を避けること」のバランスを意識して使ってみてほしい。君が管理するデータベースが、より堅牢で、かつメンバーにとって使いやすい環境になることを応援しているよ。

さて、今日はここまで。何か詰まったらまたいつでも聞いてくれ!

コメント

タイトルとURLをコピーしました