Oracleの稼働状況を監視するため、メモリー上の統計情報をリアルタイムに開示する動的パフォーマンスビューを活用します。
実行に必要な権限と環境 以下のビューを参照するには、
SYSDBA権限、またはSELECT ANY DICTIONARYもしくはSELECT_CATALOG_ROLEロールが必要です。また、マルチテナント環境(CDB/PDB)では、調査対象のプラガブル・データベース(PDB)に接続してSQLを実行してください。元記事内のSQLコマンドをそのまま利用して解説します。


💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
1. v$session の見方
現在のセッションごとのリアルタイムな状態(アクティブ/非アクティブ)や、今まさに直面している待機イベントを確認できます。
SELECT sid, serial#, status, event, wait_class, state
FROM v$session
WHERE username IS NOT NULL;
SQLの意図と結果: バックグラウンドプロセスを除外した一般ユーザーセッションの一覧を取得します。各セッション(
sid)が現在待機しているイベント名(event)やその大分類(wait_class)、および待機状態の詳細(state)を把握できます。
2. v$session_event の見方
接続中のセッションが、過去から現在までに累積でどれだけの回数、どのイベントで待たされたかを保持しています。
SELECT sid, event, total_waits, time_waited
FROM v$session_event
WHERE event NOT LIKE 'SQL*Net%';
SQLの意図と結果: クライアントとの通信待ち(アイドルイベント)である
SQL*Net%をフィルタリングで除外し、各セッションが実務的な処理で引っかかった累計待機回数(total_waits)と累計待機時間(time_waited)をリストアップします。
3. v$system_event の見方
インスタンス全体において、データベースが起動してから発生したすべての待機イベントの累積統計情報が格納されています。
SELECT event, total_waits, time_waited, average_wait
FROM v$system_event
WHERE event NOT LIKE 'SQL*Net%';
SQLの意図と結果: システム全体の総合的なボトルネックを洗い出します。平均待機時間(
average_wait)が異常に長いイベントを特定することで、ストレージのI/O性能不足やアプリケーション全体の設計上の不備をマクロに評価できます。
4. v$session_wait の補足
-- (参考:Oracle 10g以前の古い環境との互換用)
-- Oracle 10g以降は v$session に同様の列が統合されているため、通常は v$session で事足ります。
5. RAC(Real Application Clusters)環境での注意点:gv$ビュー の活用
RAC環境では複数のデータベースインスタンスが同時に稼働しています。特定の1インスタンスだけでなく、クラスタ全体のセッション情報を一括で串刺し検索するには、グローバル動的パフォーマンスビューである gv$ビュー を使用します。
SELECT inst_id, sid, serial#, event, wait_class, state
FROM gv$session
WHERE username IS NOT NULL;
SQL of the intent and results: クラスタ内の全インスタンスを横断してセッションを抽出します。出力結果の
inst_id(インスタンスID)を確認することで、どのノード(サーバー)に負荷や待機イベントが集中しているかを即座に特定可能です。
【実例】ロック競合を発生させて待機イベントを確認する検証手順
待機イベントの挙動を深く理解するために、意図的に「行ロック(TXロック)のバッティング」を発生させ、動的パフォーマンスビューにどのようなデータが記録されるかを実機で確認するステップです。
1. テスト用表の作成
まずは検証用のクリーンな環境にテスト用のテーブルと初期データを準備します。
CREATE TABLE lock_test (
id NUMBER PRIMARY KEY,
name VARCHAR2(50)
);
INSERT INTO lock_test VALUES (1, 'taro');
COMMIT;
2. セッションAで更新してロックを保持
コマンドラインツール(SQL*Plus等)のターミナル1(セッションA)を開き、以下の UPDATE 文を実行します。注意:ここではまだ COMMIT や ROLLBACK を行わないでください。
UPDATE lock_test SET name = 'jiro' WHERE id = 1;
- セッションAの画面出力結果:
SQL> UPDATE lock_test SET name = 'jiro' WHERE id = 1; ★UPDATEを実行(commitしない)
1行が更新されました。
SQL>
現在の状態: セッションAが
id = 1の行に対して「排他ロック(行ロック)」を獲得し、トランザクションが継続した状態のまま留まっています。
3. セッションBで同じ行を更新し、ロック待ちにさせる
別のウィンドウで新しいコマンドラインツールを開き、ターミナル2(セッションB)としてデータベースに接続します。セッションAがロックを保持したままの状態の id = 1 の行に対して、異なる値での更新を試みます。
UPDATE lock_test SET name = 'saburo' WHERE id = 1;
- セッションBの画面出力結果:
SQL> UPDATE lock_test SET name = 'saburo' WHERE id = 1; ★コマンドが完了せず待機する
現在の状態: 先行するセッションAがコミットを打っていないため、セッションBは行の更新権利を得られず、内部的にロック解除待ちの状態として処理が完全にブロックされます。
4. セッションBの待機イベント確認(監視セッション)
さらに別のターミナル3(監視用の別セッション)を開き、v$session ビューからセッションBがどのような状態で停止しているかを検索・確認します(検索条件の '対象のユーザー名' は環境に応じて 'USER1' などの適切なスキーマ名に変更してください)。
SELECT sid, event, wait_class, state
FROM v$session
WHERE username = '対象のユーザー名';
- 監視結果の出力サンプル:
SQL> SELECT sid, event, wait_class, state
2 FROM v$session
3 WHERE username = 'USER1';
SID EVENT WAIT_CLASS STATE
---------- ------------------------------ ------------------------- --------------------
62 SQL*Net message from client Idle WAITING
82 enq: TX - row lock contention Application WAITING ★
解析結果の解説:
SID = 62(セッションA側)は、クライアントからの次の入力コマンドを待っているアイドル状態(SQL*Net message from client)です。- 一方で
SID = 82(セッションB側)は、待機イベントenq: TX - row lock contention、待機クラスApplication、状態WAITINGと表示されています。これにより、アプリケーションのトランザクション設計に起因する行ロック競合で処理が完全にせき止められている事実を、明確なデータとして証明・捕捉できました。事後処理の実行手順: 検証完了後は、ターミナル1(セッションA)側で
COMMIT;またはROLLBACK;を実行してください。ロックが解放された瞬間にターミナル2(セッションB)の処理が即座に完了します(完了後はセッションB側でも同様にCOMMIT;を行って終了してください)。
運用・監視・セキュリティ上の注意点
- ロック調査時の安全な対処アプローチ(参照系の優先): 実際の運用本番環境で
enq: TX - row lock contentionなどの激しいロック競合を発見した場合、原因となっている先行セッション(ロックを保持したまま応答がないセッションなど)をALTER SYSTEM KILL SESSIONコマンド等で強制終了させることで、待たされている後続の処理を強制解放することができます。 ただし、強制終了を行う前に必ずv$lockやv$blocking_sessionなどの参照系ビューを用いて、「どのセッション(SID)が、どのセッションをブロックしているのか」の正確な親子関係(ロックツリー)を特定してください。誤って重要なオンライン処理やバッチセッションを強制終了すると、トランザクションのロールバックに伴うデータベースのオーバーヘッドやデータの不整合を引き起こす二次災害に繋がるリスクがあります。 - 統計情報の解釈における「アイドルイベント」の除外:
v$system_eventなどを分析する場合、SQL*Net message from clientやrdbms ipc messageといったアイドルイベント(データベースがやることがなく、ユーザーからの要求や命令を単に待っているだけの状態を示すイベント)は高確率で累積時間の最上位を占めます。これらはシステムのボトルネックではないため、チューニング対象の評価からは必ず除外して、User I/OやConcurrencyといった実働を伴う待機クラスの数値に焦点を当てて監視を行う必要があります。
FAQ:よくある質問
Q1. db file sequential read が頻発しています。ディスクの性能アップが必要ですか?
A1. いいえ、必ずしもハードウェアの増強が正解とは限りません。このイベントはインデックス経由のアクセス(単一ブロック読み込み)の遅延を示しますが、原因の多くは「インデックスの選択性が悪く、結果的に大量の行を1ブロックずつ非効率に読み込んでいる」ことにあります。まずは対象SQLの実行計画を確認し、適切なインデックス設計への見直し、または SHARED_POOL や BUFFER CACHE のサイズ適正化を行うことが先決です。
Q2. 待機イベントの時間はミリ秒ですか? それとも秒ですか?
A2. 動的パフォーマンスビューの time_waited 列の単位は、バージョンやビューの仕様により異なりますが、原則として100分の1秒(センチ秒)単位で保持されているケースが多く見られます。ただし、より詳細な時間計測が行える v$session_history や、近年のバージョンにおける一部の関連ビューではマイクロ秒単位で記録されている列(time_waited_micro など)も存在するため、正確な評価を行う際は各列の定義を確認してください。
Q3. RAC環境で v$session を使うと、別ノードのセッションは見えませんか?
A3. はい、見えません。v$session は接続している該当インスタンス内のセッション情報のみを表示します。クラスタを構成する他のインスタンス上の挙動を含めて全量を確認したい場合は、必ず本記事内のスクリプト例にあるように、頭に G がついた gv$session を使用して検索を行ってください。
まとめ:待機イベント分析の4大原則
- システムの「遅い」をイベント名で言語化・数値化する(勘に頼らない)
- 状況に応じてビューを使い分ける(リアルタイムは
v$session、全体傾向はv$system_event) - RAC環境では必ず
gv$ビューでクラスタ全体を鳥瞰する - 意図的な再現テストを活用し、問題発生時のビューの挙動をあらかじめ把握しておく
本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。
[参考]
C.3 待機イベントの説明

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


コメント