LoginSignup
1
0

More than 3 years have passed since last update.

システム・トリガーを試す(1)(Oracle Database 19c)

Last updated at Posted at 2021-04-04

Oracle Database上で何等かのイベントが発生した場合にプログラムを実行する仕組みをトリガーと呼びます。トリガーはCREATE TRIGGER文で登録します。一般的にはテーブルに対して作成され、レコードの INSERT / DELETE / UPDATE の単位で何等かのプログラム(通常 PL/SQL プロシージャ)を実行したい場合に使用します。トリガーの実行タイミング(BEFORE / AFTER)や、レコード単位(FOR EACH ROW)/文単位に実行する等の設定を行うことができます。

システム・トリガー

この記事で紹介するのは、テーブルに格納されたレコードの更新やDML単位ではなくOracle Databaseインスタンス上で発生したイベントに対するトリガーです。CREATE TRIGGER文のマニュアルでは system_trigger と記載されています。例えば以下のようなイベントでトリガーを実行可能です。

DDL Event

何等かのDDLが実行された場合に発行されるトリガーです。

イベント 説明
ALTER ALTER DATABASE文を除くALTER文の実行
ANALYZE 統計情報の制御
AUDIT AUDIT文の発行
ASSOCIATE STATISTICS 統計タイプがオブジェクトに関連付けられる
COMMENT コメントが追加される
CREATE CREATE文でオブジェクト作成
DROP オブジェクト削除
GRANT 権限の付与
NOAUDIT NOAUDIT文の実行
RENAME オブジェクト名の変更
REVOKE 権限のはく奪
TRUNCATE TRUNCATE文の実行
DDL 上記のいずれかのDDLの実行

DATABASE Event

 データベース上のイベントが発生した場合に発行されるトリガーです。

イベント 説明
AFTER STARTUP データベースがオープンされた
BEFORE SHUTDOWN インスタンスが停止されようとしている
AFTER DB_ROLE_CHANGE ロールが変更された
AFTER SERVERERROR エラーが発生した
AFTER LOGON クライアントが接続した
BEFORE LOGOFF クライアントが切断しようとしている
AFTER SUSPEND トランザクションが停止した
BEFORE UNPLUG PDBが切断されようとしている
BEFORE or AFTER SET CONTAINER ALTER SESSION SET CONTAINERの実行前後

インスタンスのトリガー

この中でインスタンス起動/停止時に実行されるトリガーを試します。

AFTER STARTUP TRIGGER

 データベース・インスタンスが起動した場合に実行されるトリガーです。AFTER STARTUP ON DATABASE句を使ってトリガーstartup_trigger1を作成します。下記の例ではトリガーが起動されると、現在時刻と「: AFTER STARTUP TRIGGER」文をアラーとログに書き込みます。

SQL> CREATE OR REPLACE TRIGGER startup_trigger1 AFTER STARTUP ON DATABASE
BEGIN
    DBMS_SYSTEM.KSDWRT(2, TO_CHAR(SYSTIMESTAMP) || ': AFTER STARTUP TRIGGER');
END;
/
トリガーが作成されました

インスタンスを起動してアラートログを確認します。

[5725] Successfully onlined Undo Tablespace 2.
Undo initialization online undo segments: err:0 start: 1885769 end: 1885828 diff: 59 ms (0.1 seconds)
Undo initialization finished serial:0 start:1885752 end:1885831 diff:79 ms (0.1 seconds)
Verifying minimum file header compatibility for tablespace encryption..
Verifying file header compatibility for tablespace encryption completed for pdb 0
Database Characterset is AL32UTF8
No Resource Manager plan active
joxcsys_required_dirobj_exists: directory object exists with required path /u01/app/oracle/product/19.0.0/dbhome_1/javavm/admin/, pid 5725 cid 0
replication_dependency_tracking turned off (no async multimaster replication found)
Starting background process AQPC
2021-04-04T16:23:51.852272+09:00
AQPC started with pid=41, OS id=5733
21-04-04 16:23:52.035240000 +09:00: AFTER STARTUP TRIGGER
Starting background process CJQ0
2021-04-04T16:23:52.051488+09:00
CJQ0 started with pid=42, OS id=5754
Completed: ALTER DATABASE OPEN
2021-04-04T16:23:52.138424+09:00
TMON (PID:5713): STARTING ARCH PROCESSES
Starting background process ARC1
2021-04-04T16:23:52.147342+09:00
ARC1 started with pid=51, OS id=5758
Starting background process ARC2
2021-04-04T16:23:52.156730+09:00

上記でわかるように、「Completed: ALTER DATABASE OPEN」のログが出力される直前にトリガーが実行されていることがわかります。この時点ではアーカイバ・プロセスは起動していません。またインスタンスがオープンされないと実行されないため、Data Guardスタンバイ・インスタンスでは通常は実行されません。

BEFORE SHUTDOWN TRIGGER

 SHUTDOWNコマンドを実行され、データベース・インスタンスが停止した場合に実行されるトリガーです。BEFORE SHUTDOWN ON DATABASE句を使ってshutdown_trigger1トリガーを作成します。下記の例ではトリガーが起動されると、現在時刻と「: BEFORE SHUTDOWN TRIGGER」文をアラーとログに書き込みます。

SQL> CREATE OR REPLACE TRIGGER shutdown_trigger1 BEFORE SHUTDOWN ON DATABASE
BEGIN
    DBMS_SYSTEM.KSDWRT(2, TO_CHAR(SYSTIMESTAMP) || ': BEFORE SHUTDOWN TRIGGER');
END;
/
トリガーが作成されました

インスタンスを停止してアラートログを確認します。

2021-04-04T16:22:26.735204+09:00
Shutting down ORACLE instance (immediate) (OS id: 4354)
2021-04-04T16:22:26.743418+09:00
Shutdown is initiated by sqlplus@rel78-2 (TNS V1-V3).
Stopping background process SMCO
2021-04-04T16:22:28.900938+09:00
Shutting down instance: further logons disabled
2021-04-04T16:22:29.052145+09:00
Stopping background process CJQ0
Stopping background process MMNL
2021-04-04T16:22:30.059440+09:00
Stopping background process MMON
2021-04-04T16:22:32.060912+09:00
21-04-04 16:22:32.060808000 +09:00: BEFORE SHUTDOWN TRIGGER
License high water mark = 4
Stopping Emon pool
2021-04-04T16:22:32.062000+09:00
Stopping all emon processes
Stopping EMNC
2021-04-04T16:22:32.071580+09:00
Stopping all emon processes
Dispatchers and shared servers shutdown

SHUTDOWNコマンドを実行し、いくつかのバックグラウンド・プロセス停止後にトリガーが動作していることがわかります。Data Guardスタンバイ・インスタンスのシャットダウンではログが出力されなかったため、スタンバイ・インスタンスではトリガーは起動しないのかもしれません。

BEFORE SHUTDOWNトリガーはインスタンスの異常終了時には実行されないようです。LGWRプロセスを強制終了した際のアラートにはトリガーの実行を示すログは出力されませんでした。

PMON (ospid: 34140): terminating the instance due to ORA error 470
2021-04-05T09:01:22.208708+09:00
Cause - 'Instance is being terminated due to fatal process death (pid: 20, ospid: 34177, LGWR)'
2021-04-05T09:01:22.218169+09:00
System state dump requested by (instance=1, osid=34140 (PMON)), summary=[abnormal instance termination].
System State dumped to trace file /u01/app/oracle/diag/rdbms/o19a/O19A/trace/O19A_diag_34160.trc
2021-04-05T09:01:22.532299+09:00
Dumping diagnostic data in directory=[cdmp_20210405090122], requested by (instance=1, osid=34140 (PMON)), summary=[abnormal instance termination].
2021-04-05T09:01:23.618609+09:00
Instance terminated by PMON, pid = 34140
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0