Oracleのセッション一覧を確認・強制切断する方法【V$SESSION活用SQL集】

当ページのリンクには広告が含まれています。

Oracleを運用していると、こんな場面が必ずきます。

  • 誰かのSQL処理がハングしてDBが重くなっている
  • 不要なセッションが大量に接続されている
  • ロックが解放されず後続処理が詰まっている

そんなときに使うのが V$SESSION ビューと ALTER SYSTEM KILL SESSION コマンドです。

この記事では、現場SE歴20年超の筆者がOracleのセッション一覧を確認するSQLセッションを強制切断する手順を、実際の運用で使えるレベルで解説します。


目次

V$SESSIONとは

V$SESSION はOracleの動的パフォーマンスビューで、現在DBに接続しているすべてのセッション情報が格納されています。

参照には DBA権限(system / sys)、または SELECT ANY DICTIONARY 権限が必要です。


基本:接続中のセッション一覧を確認する

sql

SELECT
    SID
   ,SERIAL#
   ,USERNAME        AS ユーザー名
   ,STATUS          AS 状態
   ,MACHINE         AS 接続元マシン名
   ,PROGRAM         AS 接続プログラム
   ,MODULE          AS モジュール名
   ,LOGON_TIME      AS ログイン日時
   ,LAST_CALL_ET    AS 最終操作からの経過秒
FROM V$SESSION
WHERE USERNAME IS NOT NULL   -- バックグラウンドプロセスを除外
ORDER BY LOGON_TIME ASC
;

STATUSの意味

STATUS値意味
ACTIVE現在SQLを実行中
INACTIVE接続中だがSQL未実行(アイドル)
KILLEDKILL SESSION実行済み(まだ完全終了していない)
CACHEDセッションキャッシュ中

応用:ユーザー別のセッション数を集計する

接続数が多い原因を調べるときに使います。

sql

SELECT
    USERNAME        AS ユーザー名
   ,STATUS          AS 状態
   ,COUNT(*)        AS セッション数
FROM V$SESSION
WHERE USERNAME IS NOT NULL
GROUP BY USERNAME, STATUS
ORDER BY セッション数 DESC
;

応用:長時間実行中のセッションを抽出する

LAST_CALL_ET(最終操作からの経過秒)が大きいセッションを探します。

sql

SELECT
    SID
   ,SERIAL#
   ,USERNAME
   ,STATUS
   ,LAST_CALL_ET    AS 経過秒
   ,SQL_ID
   ,MACHINE
   ,PROGRAM
FROM V$SESSION
WHERE USERNAME IS NOT NULL
  AND STATUS = 'ACTIVE'
  AND LAST_CALL_ET > 300   -- 5分以上実行中のものを抽出
ORDER BY LAST_CALL_ET DESC
;

応用:実行中のSQLも一緒に確認する

どんなSQLを実行しているかを V$SQL と結合して確認できます。

sql

SELECT
    S.SID
   ,S.SERIAL#
   ,S.USERNAME
   ,S.STATUS
   ,S.LAST_CALL_ET  AS 経過秒
   ,S.MACHINE
   ,S.PROGRAM
   ,Q.SQL_TEXT      AS 実行中SQL
FROM V$SESSION S
LEFT JOIN V$SQL Q ON S.SQL_ID = Q.SQL_ID
WHERE S.USERNAME IS NOT NULL
  AND S.STATUS = 'ACTIVE'
ORDER BY S.LAST_CALL_ET DESC
;

セッションを強制切断する(KILL SESSION)

特定のセッションを強制終了するには ALTER SYSTEM KILL SESSION を使います。

手順1:切断対象のSIDとSERIAL#を確認

sql

SELECT SID, SERIAL#, USERNAME, STATUS, MACHINE, PROGRAM
FROM V$SESSION
WHERE USERNAME = '切断したいユーザー名'
;

手順2:KILL SESSIONを実行

sql

ALTER SYSTEM KILL SESSION 'SID, SERIAL#' IMMEDIATE;

-- 実行例(SID=45、SERIAL#=1234の場合):
ALTER SYSTEM KILL SESSION '45, 1234' IMMEDIATE;

IMMEDIATEをつける理由: つけないと、Oracleがセッションに自発的に終了するよう要求するだけで、実際の終了まで数分かかることがあります。緊急時は必ず IMMEDIATE を指定してください。


複数セッションをまとめて切断する

特定ユーザーの全セッションをまとめて切断したい場合は、以下のPL/SQLブロックが便利です。

sql

BEGIN
    FOR s IN (
        SELECT SID, SERIAL#
        FROM V$SESSION
        WHERE USERNAME = '切断したいユーザー名'
          AND STATUS   = 'INACTIVE'   -- アイドルセッションのみを対象
    ) LOOP
        EXECUTE IMMEDIATE
            'ALTER SYSTEM KILL SESSION ''' || s.SID || ',' || s.SERIAL# || ''' IMMEDIATE';
    END LOOP;
END;
/

⚠️ ACTIVE セッションを強制切断すると、実行中のトランザクションがロールバックされます。業務への影響を必ず確認してから実行してください。


KILL後もセッションが消えない場合

STATUS = 'KILLED' のセッションが残り続けることがあります。これはOracleがロールバック処理中の場合です。

sql

-- KILLED状態のセッションを確認
SELECT SID, SERIAL#, STATUS, USERNAME, LAST_CALL_ET
FROM V$SESSION
WHERE STATUS = 'KILLED'
;

通常はロールバックが完了すると自動的に消えます。長時間(30分以上)消えない場合は、OSプロセスを強制終了することも検討します(DBA判断で実施)。


よくある質問(FAQ)

Q. 自分自身のセッションを切断できますか?

自分自身のセッションはKILLできません。別の管理者アカウントで実行する必要があります。

Q. V$SESSIONを見るにはどんな権限が必要ですか?

SELECT ANY DICTIONARY 権限、または DBA ロールが必要です。一般ユーザーはデフォルトでは参照できません。

Q. セッションを切断するとデータが消えますか?

KILL SESSIONを実行すると、そのセッションの未コミットトランザクションは自動的にロールバックされます。コミット済みのデータには影響しません。

Q. セッション一覧に同じSIDが複数出ます。なぜですか?

USERNAME IS NOT NULL の条件で絞ればバックグラウンドプロセスは除外できます。それでも重複する場合、接続プーリングなどで同一ユーザーが複数セッションを持っています。


まとめ

用途使うSQL/コマンド
全セッション一覧SELECT FROM V$SESSION WHERE USERNAME IS NOT NULL
ユーザー別集計GROUP BY USERNAME, STATUS
長時間実行セッションWHERE LAST_CALL_ET > 秒数
実行中SQLの確認VSESSION+VSESSION + V SESSION+VSQL結合
単一セッションの切断ALTER SYSTEM KILL SESSION ‘SID,SERIAL#’ IMMEDIATE
複数セッションの一括切断PL/SQLループでKILL

V$SESSION はOracleの運用に欠かせないビューです。定期的に確認する習慣をつけておくと、トラブルの早期発見につながります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

ITの事や自分の経験談など綴っていきたいと思っています。

コメント

コメントする

CAPTCHA


目次