DBMS_TRACE は、PL/SQLのプロシージャ、ファンクション、例外、SQL、行番号の実行経路を追跡するためのOracle標準パッケージです。「どのサブプログラムがどの順番で呼ばれたか」「例外がどこで発生し、どこで処理されたか」を見たいときに役立ちます。
一方で、DBMS_TRACE は性能ボトルネックを測るための第一候補ではありません。時間や行別の実行回数を詳しく見たい場合は DBMS_PROFILER / DBMS_HPROF、運用監視で現在処理中のモジュールを見たい場合は DBMS_APPLICATION_INFO が向きます。この記事では、DBMS_TRACEを呼び出し経路と例外発生箇所の調査に絞って実務向けに整理します。性能分析は PL/SQLプロファイラ完全ガイド、運用観測性は DBMS_APPLICATION_INFO完全ガイド も参考にしてください。
DBMS_TRACEで分かること、分からないことtracetab.sqlによるトレース表の準備SET_PLSQL_TRACE/CLEAR_PLSQL_TRACEの基本TRACE_LIMITと enabled program unit によるデータ量制御PLSQL_TRACE_RUNS/PLSQL_TRACE_UNITS/PLSQL_TRACE_EVENTSの読み方- 例外発生箇所を追うSQL
- 本番利用時の注意点と削除方針
DBMS_TRACEで分かること
DBMS_TRACEは、PL/SQLプログラムの実行中に発生した呼び出し、戻り、例外、SQL、行番号の変化をデータベース内の表に記録します。公式ドキュメントでも、PL/SQL関数・プロシージャ・例外をトレースするためのインターフェースとして説明されています。
DBMS_PROFILERやログとの使い分け
DBMS_TRACEは「経路」を見る道具です。時間計測やボトルネック特定は、DBMS_PROFILERやDBMS_HPROFのほうが向いています。一方、業務ログや監査ログは、あとから運用上の事実を追うためのものです。目的ごとに使い分けます。
PL/SQL側の行レベル性能分析は DBMS_PROFILERで行レベル分析する完全ガイド、運用ログやトレーサビリティ設計は ロギングとトレーサビリティを両立する監査設計 が近いテーマです。
前提準備: tracetab.sqlを実行する
DBMS_TRACEの出力は、データベース内のトレース表へ保存されます。そのため、事前にOracle付属スクリプト tracetab.sql を実行して、PLSQL_TRACE_RUNS、PLSQL_TRACE_UNITS、PLSQL_TRACE_EVENTS などを作成しておく必要があります。公式ドキュメントでも、表がない場合はデータが収集されないと説明されています。
-- DBAまたは管理者が一度だけ実行する例 -- 環境によりパスは異なります @$ORACLE_HOME/rdbms/admin/tracetab.sql -- 作成後の確認例 SELECT table_name FROM all_tables WHERE table_name LIKE 'PLSQL_TRACE_%' ORDER BY table_name;
最小手順: 有効化して対象処理を実行する
最小構成では、現在セッションでトレースを有効化し、対象処理を実行し、最後に必ず無効化します。CLEAR_PLSQL_TRACE を忘れると、想定外の処理まで記録されます。
BEGIN
DBMS_TRACE.SET_PLSQL_TRACE(
DBMS_TRACE.TRACE_ALL_CALLS +
DBMS_TRACE.TRACE_ALL_EXCEPTIONS
);
target_pkg.run_job(p_job_id => 1001);
DBMS_TRACE.CLEAR_PLSQL_TRACE;
EXCEPTION
WHEN OTHERS THEN
DBMS_TRACE.CLEAR_PLSQL_TRACE;
RAISE;
END;
/
例外時にも CLEAR_PLSQL_TRACE を呼ぶ形にしておくのが安全です。調査用SQLを何度も実行する場合は、この形をテンプレート化しておくとトレース停止漏れを防げます。
トレースレベルの選び方
DBMS_TRACEは、複数の定数を足し合わせてトレース対象を指定します。最初から全行・全SQLを取ると分析しづらい量になるため、まずは呼び出しと例外だけに絞るのがおすすめです。
-- 呼び出し経路と例外だけを見る DBMS_TRACE.SET_PLSQL_TRACE( DBMS_TRACE.TRACE_ALL_CALLS + DBMS_TRACE.TRACE_ALL_EXCEPTIONS + DBMS_TRACE.TRACE_LIMIT ); -- 行番号まで見る場合。短時間だけ使う DBMS_TRACE.SET_PLSQL_TRACE( DBMS_TRACE.TRACE_ALL_LINES + DBMS_TRACE.TRACE_ALL_EXCEPTIONS + DBMS_TRACE.TRACE_LIMIT );
対象を絞る: enabled program unit
大きなアプリケーションで全サブプログラムをトレースすると、データ量が膨らみます。DBMS_TRACEでは、特定のプログラムユニットをDEBUG付きでコンパイルし、TRACE_ENABLED_CALLS や TRACE_ENABLED_EXCEPTIONS を使って対象を絞れます。
-- 対象パッケージだけDEBUG付きで再コンパイルする例
ALTER PACKAGE target_pkg COMPILE BODY DEBUG;
-- enabled program unit を中心にトレースする
BEGIN
DBMS_TRACE.SET_PLSQL_TRACE(
DBMS_TRACE.TRACE_ENABLED_CALLS +
DBMS_TRACE.TRACE_ENABLED_EXCEPTIONS +
DBMS_TRACE.TRACE_LIMIT
);
target_pkg.run_job(1001);
DBMS_TRACE.CLEAR_PLSQL_TRACE;
END;
/
公式ドキュメントでは、全体をトレースすると管理しにくい大量データになるため、特定プログラムユニットへ絞る方法が案内されています。本番に近い環境では、まず対象パッケージを絞るのが現実的です。
直近のトレースランを確認する
トレース実行後は、まず直近のランを特定します。環境やバージョンにより列名の詳細は異なる場合がありますが、基本的には PLSQL_TRACE_RUNS から実行単位を確認し、RUNIDを起点にイベントやユニットを見ます。
SELECT * FROM ( SELECT runid, run_date, run_owner, run_comment FROM plsql_trace_runs ORDER BY runid DESC ) WHERE ROWNUM <= 5;
チーム運用では、トレース実行前にコメントや別途管理ログへ目的を残しておくと、あとから何の調査だったか分かりやすくなります。
呼び出し経路を読む
呼び出し経路を見るときは、イベント表とユニット表をRUNIDで結び、イベント順に並べます。コール、リターン、例外、行番号のどれを見たいかで絞り込みます。
SELECT e.runid, e.event_seq, e.event_kind, e.unit_owner, e.unit_name, e.line, e.depth FROM plsql_trace_events e WHERE e.runid = :runid ORDER BY e.event_seq;
実際の列名やイベント値は環境により確認が必要です。まず DESC PLSQL_TRACE_EVENTS で列を確認し、自分の環境に合わせて分析SQLを調整してください。
例外発生箇所を追う
DBMS_TRACEの強い使いどころは、例外がどこで発生し、どこで処理されたかを追うことです。通常のログに「エラーになった」しか残っていない場合でも、トレースを取ると呼び出し経路と行番号の手がかりが得られます。
SELECT
event_seq,
event_kind,
unit_owner,
unit_name,
line,
exception_number,
exception_name
FROM plsql_trace_events
WHERE runid = :runid
AND (
UPPER(event_kind) LIKE '%EXCEPTION%'
OR exception_number IS NOT NULL
)
ORDER BY event_seq;
コンパイルエラーや無効オブジェクトを疑う場合は、DBMS_TRACEより先に USER_ERRORS や USER_OBJECTS を確認します。そのあたりは PL/SQLコンパイル時エラーと警告の完全対処ガイド にまとめています。
行トレースは短時間だけ使う
TRACE_ALL_LINES は、行番号が変わるたびにレコードを追加します。細かい経路を追える反面、データ量が非常に増えます。広い範囲に対して長時間有効化するのではなく、再現手順を絞って短時間だけ使います。
BEGIN
DBMS_TRACE.SET_PLSQL_TRACE(
DBMS_TRACE.TRACE_ALL_LINES +
DBMS_TRACE.TRACE_ALL_EXCEPTIONS +
DBMS_TRACE.TRACE_LIMIT
);
-- 再現に必要な最小処理だけ実行する
target_pkg.reproduce_error(p_id => 1001);
DBMS_TRACE.CLEAR_PLSQL_TRACE;
EXCEPTION
WHEN OTHERS THEN
DBMS_TRACE.CLEAR_PLSQL_TRACE;
RAISE;
END;
/
TRACE_LIMITで大量出力を抑える
TRACE_LIMIT を指定すると、直近の一定件数を残す形でデータ量を抑えられます。公式ドキュメントでは、問題箇所に至るまでの直近レコードを残し、大量の無関係データでデータベースを埋めないための指定として説明されています。再現直前にトレースを開始し、再現後すぐ停止する運用と組み合わせます。
BEGIN
DBMS_TRACE.SET_PLSQL_TRACE(
DBMS_TRACE.TRACE_ALL_CALLS +
DBMS_TRACE.TRACE_ALL_EXCEPTIONS +
DBMS_TRACE.TRACE_LIMIT +
DBMS_TRACE.NO_TRACE_ADMINISTRATIVE
);
target_pkg.run_job(1001);
DBMS_TRACE.CLEAR_PLSQL_TRACE;
END;
/
トレース表を定期的に整理する
DBMS_TRACEの出力表は、調査のたびに増えます。開発環境でも、本番に近い検証環境でも、保存期間と削除方針を決めます。調査中のRUNIDを削除しないよう、古いRUNIDだけを対象にするなどのルールが必要です。
-- 例: 古いRUNIDを確認してから削除する SELECT runid, run_date, run_owner, run_comment FROM plsql_trace_runs WHERE run_date < SYSDATE - 30 ORDER BY runid; -- 実際の削除は環境の外部キー・権限・運用ルールに合わせて行う -- 先にevents/unitsを消し、最後にrunsを消すなど、環境の定義を確認する
本番で使うときの注意
DBMS_TRACEは便利ですが、本番で常時有効にするものではありません。調査対象、対象セッション、実行時間、取得レベル、停止手順、削除方針を決めてから使います。特に全呼び出し・全行・全SQLを広範囲に取ると、性能影響とデータ量の両方が問題になります。
DBMS_APPLICATION_INFOと組み合わせる
DBMS_TRACEは調査時の詳細記録、DBMS_APPLICATION_INFOは普段の運用監視に向いています。PL/SQLバッチでは、通常時はモジュール・アクションを設定し、障害調査時だけDBMS_TRACEを使う構成が扱いやすいです。
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'BATCH_ORDER_IMPORT',
action_name => 'VALIDATE_INPUT'
);
order_import_pkg.validate_input(p_batch_id => 1001);
DBMS_APPLICATION_INFO.SET_ACTION('IMPORT_DATA');
order_import_pkg.import_data(p_batch_id => 1001);
END;
/
PL/SQLで運用観測性を高める実装は DBMS_APPLICATION_INFOで運用観測性を底上げ でも詳しく扱っています。
トラブルシュート
tracetab.sql が実行済みか、対象セッションでSET_PLSQL_TRACEしているか確認します。TRACE_LIMIT、enabled program unit、短時間実行で絞ります。TRACE_ALL_EXCEPTIONS または TRACE_ENABLED_EXCEPTIONS が指定されているか確認します。よくある質問
まとめ
DBMS_TRACE は、PL/SQLの呼び出し経路、例外発生箇所、行番号の流れを追うための調査ツールです。事前に tracetab.sql でトレース表を用意し、SET_PLSQL_TRACE で有効化し、対象処理を実行したら CLEAR_PLSQL_TRACE で必ず停止します。
使うときは、最初から全行・全SQLを取らず、呼び出しと例外を中心に短時間だけ取得します。必要に応じて TRACE_LIMIT や enabled program unit を使い、データ量を抑えましょう。性能測定はDBMS_PROFILER/HPROF、運用監視はDBMS_APPLICATION_INFO、業務キーの追跡はログ設計、と役割分担すると、DBMS_TRACEを過不足なく使えます。
参考: Oracle Database PL/SQL Packages and Types Reference – DBMS_TRACE

