Oracleロックの確認と解除方法【V$LOCK・V$SESSION完全ガイド】

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

Oracleデータベースで「テーブルが更新できない」「クエリが返ってこない」といった症状の原因の多くはロック競合です。本記事では、ロックの状態を確認するSQLと、ロックを解除(セッションのKILL)する手順を解説します。


目次

1. Oracleのロックとは {#about-lock}

Oracleでは、DML操作(INSERT・UPDATE・DELETE)を実行すると行レベルのロックが自動的に取得されます。このロックはCOMMITまたはROLLBACKが実行されるまで保持されます。

ロック競合が発生すると、後から同じ行を操作しようとしたセッションはロックが解放されるまで待機します。長時間のロック保持はシステムの停止につながるため、迅速な原因特定と対処が重要です。

ロック競合が起きる典型的なケース:

  • UPDATEしたままCOMMITを忘れている
  • バッチ処理が途中で止まっている
  • アプリケーションのトランザクション管理の不具合

2. ロック待ちのセッションを確認する {#check-lock-wait}

以下のSQLで、現在ロック待ちになっているセッションを一覧表示できます。

SELECT
    s.SID,
    s.SERIAL#,
    s.USERNAME,
    s.STATUS,
    s.MACHINE,
    s.PROGRAM,
    s.LOGON_TIME,
    s.WAIT_CLASS,
    s.EVENT,
    s.SECONDS_IN_WAIT  -- 待機している秒数
FROM
    V$SESSION s
WHERE
    s.WAIT_CLASS = 'Application'
    AND s.EVENT LIKE '%lock%'
ORDER BY
    s.SECONDS_IN_WAIT DESC;

SECONDS_IN_WAITが大きいセッションほど長時間待機しており、問題が深刻です。


3. ロックを保持しているセッションを特定する {#find-blocker}

ロック待ちを起こしている「ブロッカー(原因)」と「ウェイター(被害者)」を一覧表示します。

SELECT
    w.SID           AS WAITER_SID,      -- 待機中のSID
    w.SERIAL#       AS WAITER_SERIAL,
    w.USERNAME      AS WAITER_USER,
    b.SID           AS BLOCKER_SID,     -- ブロックしているSID
    b.SERIAL#       AS BLOCKER_SERIAL,
    b.USERNAME      AS BLOCKER_USER,
    b.MACHINE       AS BLOCKER_MACHINE,
    b.PROGRAM       AS BLOCKER_PROGRAM,
    b.LOGON_TIME    AS BLOCKER_LOGON,
    w.SECONDS_IN_WAIT
FROM
    V$SESSION w
    JOIN V$SESSION b
        ON w.BLOCKING_SESSION = b.SID
WHERE
    w.BLOCKING_SESSION IS NOT NULL
ORDER BY
    w.SECONDS_IN_WAIT DESC;

出力のポイント:

  • BLOCKER_SID / BLOCKER_SERIAL がロックを保持しているセッション
  • BLOCKER_MACHINE でどの端末・サーバーからの接続かを把握できる
  • BLOCKER_LOGON で何時からのセッションかを確認できる

4. 実行中のSQLを確認する {#check-sql}

ブロッカーが何のSQLを実行(または実行後放置)しているか確認します。

SELECT
    s.SID,
    s.SERIAL#,
    s.USERNAME,
    s.STATUS,
    sq.SQL_TEXT,     -- 実行中のSQL
    sq.LAST_ACTIVE_TIME
FROM
    V$SESSION s
    LEFT JOIN V$SQL sq
        ON s.SQL_ID = sq.SQL_ID
WHERE
    s.SID = 123;  -- ブロッカーのSIDを指定

STATUS = 'INACTIVE'かつロックを保持している場合は、COMMIT/ROLLBACKを忘れた状態であることが多いです。


5. ロックを解除する(セッションのKILL) {#kill-session}

ロックを解除するにはセッションをKILLします。対象セッションのSIDSERIAL#が必要です。

KILLコマンド

ALTER SYSTEM KILL SESSION 'SID,SERIAL#';

実行例:

ALTER SYSTEM KILL SESSION '123,456';

IMMEDIATEオプション(即時終了)

通常のKILLはOracle内部でのクリーンアップを待つ場合があります。すぐに解放したい場合はIMMEDIATEを付けます。

ALTER SYSTEM KILL SESSION '123,456' IMMEDIATE;

注意: KILL SESSIONを実行するにはALTER SYSTEM権限(通常はDBA権限)が必要です。また、KILLによりそのセッションのトランザクションはROLLBACKされます。業務影響を確認した上で実行してください。

セッションをKILLする前の確認チェックリスト

  1. KILLするセッションが正しいか(SID・SERIAL#・USERNAME・MACHINEを再確認)
  2. KILL後にROLLBACKされる更新データの業務影響を確認
  3. 可能であれば、セッションを持つ担当者・アプリへの連絡

6. DDLロック(テーブルロック)を確認する {#ddl-lock}

ALTER TABLEなどのDDLがロックを保持している場合はV$LOCKED_OBJECTDBA_OBJECTSを使います。

SELECT
    lo.SESSION_ID,
    s.SERIAL#,
    s.USERNAME,
    s.MACHINE,
    lo.ORACLE_USERNAME,
    lo.LOCKED_MODE,        -- ロックモード(2=行共有、3=行排他、など)
    do.OBJECT_NAME,        -- ロック対象のオブジェクト名
    do.OBJECT_TYPE
FROM
    V$LOCKED_OBJECT lo
    JOIN DBA_OBJECTS do
        ON lo.OBJECT_ID = do.OBJECT_ID
    JOIN V$SESSION s
        ON lo.SESSION_ID = s.SID
ORDER BY
    lo.SESSION_ID;

LOCKED_MODEの値と意味:

ロックモード
2Row Share(RS)
3Row Exclusive(RX) — 通常のDML
4Share(S)
5Share Row Exclusive(SRX)
6Exclusive(X) — DDL

7. まとめ:ロック対応の手順フロー {#summary}

【STEP 1】 ロック待ちセッションを確認
  → V$SESSION(WAIT_CLASS = 'Application')

【STEP 2】 ブロッカーを特定
  → V$SESSION の BLOCKING_SESSION 列

【STEP 3】 ブロッカーが実行中のSQLを確認
  → V$SESSION + V$SQL

【STEP 4】 ロックを解除
  → ALTER SYSTEM KILL SESSION 'SID,SERIAL#' IMMEDIATE;

用途別クエリまとめ:

目的使うビュー
ロック待ちセッションの確認V$SESSION
ブロッカー(原因)の特定V$SESSION(BLOCKING_SESSION列)
実行中SQLの確認V$SESSION + V$SQL
オブジェクトレベルのロック確認V$LOCKED_OBJECT + DBA_OBJECTS
セッションのKILLALTER SYSTEM KILL SESSION

まとめ

Oracleのロック対応は「待機セッションの確認 → ブロッカーの特定 → SQLの確認 → KILLの判断」という流れが基本です。

焦って誤ったセッションをKILLしないよう、SIDSERIAL#USERNAMEMACHINEを必ず確認してから実行しましょう。


関連記事:

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

この記事を書いた人

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

コメント

コメントする

CAPTCHA


目次