前回のおさらい
前回は、たろーちゃんの同期のAさんがお勉強用に作成した Oracle Database の状況を見てほしいと、たろーちゃんに相談したところ、実は AFTER LOGON ON DATABASE トリガーで処理が停止する PL/SQL をコーディングしてログオンできなくなり、さらにはバックアップもとっていないということが発覚したところで終わりました。
さて、たろーちゃんはこの状況を打開することができるのでしょうか?
どうすればいいの?
Aさん「どうすればいいかな?」
たろー「まず、データベースを停めよう。」
Aさん「でも、どうやって?
データベースを停めるには shutdown immediate コマンドを実行しないとダメだよな?実行しようにもログオンできないんだが・・・。」
たろー「Aさんは、Oracle Database の必須バックグラウンドプロセスって知ってる?」
Aさん「えーっと、なんだっけ?いくつかあったな。確か、Oracle Database のバージョンによっても違ったような?」
たろー「そうだ。必須バックグラウンドプロセスを OS コマンドで kill すれば、データベースが ABORT で停止するんだ。」
Aさん「ほう!」
たろー「今回は SMON を kill してみよう。ちょっと、キーボードを貸してみて。」
oracle@db7601:/home/oracle(db01s)$ ps -ef | grep smon | grep -v grep
oracle 7163 1 0 11:48 ? 00:00:00 ora_smon_db01s
たろー「これで SMON の PID が 7163 だと特定できた。これを kill するんだ。」
oracle@db7601:/home/oracle(db01s)$ kill 7163
<アラートログ>
2019-06-08T11:51:02.434998+09:00 Process termination requested for pid 7163 [source = unknown], [info = -1590624256] [request issued by pid: 3245, uid: 1000] 2019-06-08T11:51:06.364293+09:00 PMON (ospid: ): terminating the instance due to ORA error 2019-06-08T11:51:06.364425+09:00 Cause - 'Instance is being terminated due to fatal process death (pid: 23, ospid: 7163, SMON)' 2019-06-08T11:51:06.365229+09:00 System state dump requested by (instance=1, osid=7121 (PMON)), summary=[abnormal instance termination]. System State dumped to trace file /u01/app/oracle/diag/rdbms/db01s/db01s/trace/db01s_diag_7140.trc 2019-06-08T11:51:08.329201+09:00 Dumping diagnostic data in directory=[cdmp_20190608115106], requested by (instance=1, osid=7121 (PMON)), summary=[abnormal instance termination]. 2019-06-08T11:51:09.491984+09:00 Instance terminated by PMON, pid = 7121
Aさん「おおぅ。停まった。」
Oracle Database のバックグラウンドプロセス
Oracle Database では、様々なバックグラウンドプロセスが起動しています。
その中でも必須バックグラウンドプロセスは重要であり、異常終了するとDBインスタンスが停止します。
バックグラウンドプロセスの種類は Oracle Database のバージョンによっても異なるため、ここで全てを紹介することが出来ません。
ただ、現時点(2019年10月)で最新の Oracle Database は 19c です。
19c の必須バックグラウンドプロセスはこちらになりますので、ご確認ください。
たろー「さて。まずは、mount モードで起動するぞ。」
oracle@db7601:/home/oracle(db01s)$ sqlplus / as sysdba SQL*Plus: Release 19.0.0.0.0 - Production on 土 6月 8 11:51:59 2019 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. アイドル・インスタンスに接続しました。 11:52:00 SYS@db01s > startup mount ORACLEインスタンスが起動しました。 Total System Global Area 4294964000 bytes Fixed Size 9143072 bytes Variable Size 805306368 bytes Database Buffers 3472883712 bytes Redo Buffers 7630848 bytes データベースがマウントされました。
Aさん「ふむ。」
たろー「そして、隠しパラメータ _system_trig_enabled を FALSE に設定する。」
11:52:44 SYS@db01s > ALTER SYSTEM SET "_system_trig_enabled"=FALSE ; システムが変更されました。
Aさん「ほう。」
たろー「この状態でデータベースを OPEN するんだ。」
11:53:44 SYS@db01s > alter database open ; データベースが変更されました。
Aさん「どうなるんだ?」
たろー「別ターミナルでログオンしてみれば分かるさ。」
oracle@db7601:/home/oracle(db01s)$ sqlplus / as sysdba SQL*Plus: Release 19.0.0.0.0 - Production on 土 6月 8 11:25:59 2019 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. 11:54:18 SYS@db01s >
Aさん「え!普通にログオン出来た!どーしてだ?!」
たろー「隠しパラメータ _system_trig_enabled を FALSE に設定すると、システム系のトリガーが動かなくなる。これは My Oracle Support のドキュメントID 1708501.1 に書かれている情報だ。」
Aさん「そんな隠しパラメータがあるのか。」
たろー「ほら、その下らないログオントリガーを DROP してくれよ。早く。」
Aさん「お、おう!」
Aさんは問題となっていたログオントリガーを DROP 後、データベースを再起動して、ちゃんと SQL Developer からログオン出来ることを確認しました。
Aさん「いやぁ、今回はマイッタマイッタ。まさかログオン出来なくなるとはなー。」
たろー「色々興味を持って挑戦するのは良いけどさ。もしもの時のために、せめてバックアップぐらい取っておけよ。」
Aさん「いやぁ、面目ない。勉強に使ってただけだから、すっかり油断してたよ。」
たろー「あと PL/SQL のソースも、ローカルPC にテキストファイルとして、ちゃんと保存しておけよな。」
いやぁ、すまぬすまぬ。
たろー「偉そうに謝るな!
それから、自分がやったことは正直に話せ。ちゃんとした診断が下せなくなるだろ?」
Aさん「・・・いやぁ、自分がやったことがあまりに下らなく、恥ずかしくてさ・・・マジで申し訳ない。」
こうしてAさんは、愛しの PL/SQL ソースと再会することが出来ました。
今回の「心臓外科医の術式」いかがだったでしょうか?
PL/SQL でアプリケーションを開発されていらっしゃる方も多いと思いますが、ログオントリガーにはこんな落とし穴があります。
「たかがトリガーごときで、データベースが使えなくなることはない」と油断していると、痛い目に遭います。
自分がやったことがやったことだけに、Aさんのように、つい DBA にウソをついてしまうアプリケーション開発者がいるのも事実です。ウソをつかれると、心臓外科医は正確な診断が下せなくなり、助けられるものも助けられなくなってしまいます。
・・・皆様、安心して下さい。心臓外科医は皆様の味方です。
どんな些細な事でも、包み隠さず、正直に話すようにして下さい。
それでは、次回も頑張りますので、応援よろしくお願い致します。