【ORACLE】セッションの強制KILL
セッションを切断するには下記のSQLを発行する。 sysdbaじゃなくてもOK。
ALTER SYSTEM KILL SESSION '[SID],[SERIAL#]';
たとえばSID=100、SERIAL#が12345なら ALTER SYSTEM KILL SESSION '100,12345'; とする。
たいていこれで殺せるのだが、 長く続いたトランザクション処理などの場合、 セッションのステータスが「KILLED」になってロールバックを継続することがある。 ⇒V$SESSION.STATUSの値で確認できる。
この場合はおとなしくロールバックの完了を待つしかない。
ロールバック中も「ロールバックをする」という行為そのものは セッションの処理状況として保持されるので V$SESSION.SEQ#を見ることで処理進行有無は確認される。
参考:【ORACLE】長時間流れているSQLの処理状況を調査
それでも待ってられないから殺したい (たとえばLOCK解放待ちでとっとと席を空けてほしい)という場合は OS上に展開されたOracleのプロセスを殺すことで完全抹殺できる。
OS上に展開されたOracleプロセスのプロセスIDは、V$PROCESS.SPIDに記録されている。 V$PROCESSにはV$SESSION.PADDRとV$PROCESS.ADDRとを結合して参照すればよい。
SELECT P.SPID FROM V$PROCESS P WHERE P.ADDR in (SELECT PADDR FROM V$SESSION WHERE SID = :SID)
上記SQLの:SIDのバインド変数に目当てのセッションIDを入力すれば 対応するOS上のプロセスIDがわかるので、そのIDをOS毎のkillコマンドに与えて殺すだけ。
UNIX系なら
kill -9 [PID]
Windows系なら
taskkill /pid [PID]
という感じか。
ただ、まだロールバック中のプロセスをOS上からすら抹殺すると、 途中だったロールバックはRMAN?だとかいうOracleのバックグラウンドプロセスに引き継がれ、 裏でタラタラ流れることになる。
これをあまり数多く行うと負荷が高くなるので、あまりお勧めできない。 …と昔Oracleの有識者に言われた。
とはいえ業務的都合や作業内容等でそうも言ってられない実情が出てくるのも 現場の人間からすると事実だったりするものだ。
なるべくやりたくないけど、やる場合は少し「覚悟」が必要だ。 暗闇の荒野に進むべき道を切り開くのだ。