DataBase  /  SQL Server  /  レポート取得ガイド

PART 04 — Extended Events による取得とセクション定義

Extended Events(XE)は SQL Server 標準の軽量イベントトレースフレームワークです。 SQL Profiler の後継として推奨されており、SQL 実行・待機イベント・デッドロック・ エラーなどを低オーバーヘッドで取得できます。 Oracle の Diagnostics Pack の ASH(Active Session History)や Event Monitor に相当します。

SQL Profiler が非推奨だと知りつつ、Extended Events への移行を先延ばしにしていないでしょうか。私自身、セッション定義の構文の複雑さに尻込みしていましたが、実際に触ってみると拡張イベントの方が扱いやすい場面の方が多いと気づかされました。

1. Extended Events の概要とアーキテクチャ

SQL Server Extended Eventsアーキテクチャ図

図1: Extended Eventsのイベント・セッション・ターゲット構成

Extended Events は「セッション」単位でイベントを定義します。 各セッションには イベント(何を取得するか)・ アクション(取得時に付加する情報)・ ターゲット(取得したデータをどこに出力するか)を設定します。

SQL Profiler は非推奨
SQL Server Profiler は将来のバージョンで削除予定のため、新規のトレース設計では Extended Events の使用が Microsoft によって推奨されています。 Profiler に比べてオーバーヘッドが大幅に低い(約 2〜3%)という特徴があります。

2. セッションの作成と管理

セッションの基本構文

T-SQL — XE セッション作成テンプレート
CREATE EVENT SESSION [session_name] ON SERVER
ADD EVENT sqlserver.event_name (    -- 取得するイベント
    ACTION (
        sqlserver.sql_text,         -- 実行 SQL テキスト
        sqlserver.client_hostname,  -- クライアントホスト名
        sqlserver.database_name,    -- データベース名
        sqlserver.username,         -- 接続ユーザー
        sqlserver.session_id        -- セッション ID
    )
    WHERE (                         -- フィルタ条件
        [sqlserver].[database_name] = N'YourDatabase'
    )
)
ADD TARGET package0.event_file (   -- ファイルターゲット(ディスクへ保存)
    SET filename     = N'C:\XE\session_name.xel',
        max_file_size = 50,         -- MB
        max_rollover_files = 5
)
WITH (
    MAX_MEMORY            = 4096 KB,
    EVENT_RETENTION_MODE  = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY  = 5 SECONDS,
    TRACK_CAUSALITY       = OFF     -- 関連イベントの因果関係追跡
);
GO

-- セッションを開始
ALTER EVENT SESSION [session_name] ON SERVER STATE = START;

-- セッションの停止
ALTER EVENT SESSION [session_name] ON SERVER STATE = STOP;

-- セッションの削除
DROP EVENT SESSION [session_name] ON SERVER;

3. 主要イベント一覧とセクション定義

SQL 実行関連

イベント名取得タイミング主なフィールド用途
sql_statement_completed SQL 文の実行完了時 duration, cpu_time, logical_reads, writes, row_count, statement 低速 SQL の特定。duration でフィルタして重い SQL のみ取得
sql_batch_completed バッチ(バッチ全体)の実行完了時 duration, cpu_time, logical_reads, batch_text ストアドプロシージャ呼び出し全体の統計を取得したい場合
rpc_completed RPC(リモートプロシージャコール)完了時 duration, cpu_time, logical_reads, statement, object_name ADO.NET ExecuteReader / sp_executesql などを含む RPC の統計
sql_statement_starting SQL 文の実行開始時 statement 実行中の SQL テキストをリアルタイムに確認したい場合

待機・ブロッキング関連

イベント名取得タイミング主なフィールド用途
wait_info 待機の開始・終了時 wait_type, duration, opcode (begin/end) 特定の wait_type が発生した時刻・セッションを追跡
xml_deadlock_report デッドロック発生時 xml_report(デッドロックグラフ XML) デッドロックの詳細分析。system_health セッションでも自動取得
blocked_process_report ブロック時間がしきい値超過時 blocked_process(XML) 長時間ブロッキングを検知。しきい値は sp_configure で設定
lock_timeout ロックタイムアウト発生時 object_id, resource_type, lock_mode SET LOCK_TIMEOUT によるタイムアウト発生を追跡

エラー・警告関連

イベント名取得タイミング主なフィールド用途
error_reported エラー発生時 error_number, severity, message 特定エラー番号(例: 1205 デッドロック)の発生を捕捉
attention クライアントからのキャンセル(Attention パケット)受信時 duration ユーザーやアプリからのクエリキャンセルを追跡
sql_exception T-SQL 例外発生時 number, severity, message アプリで処理されている例外の発生頻度を確認

4. ターゲット種別(出力先)

ターゲット名説明推奨用途
event_file ディスク上の .xel ファイルに保存(ローリング)。SQL Server の再起動後も保持される 長期ロギング・事後分析。本番環境での推奨ターゲット
ring_buffer メモリ上のリングバッファに保持。古いイベントは自動上書き リアルタイム診断・一時的な調査。再起動でデータ消失
histogram イベントの発生回数をフィールド値別に集計するバケット 特定の wait_type や error_number の発生回数を軽量に集計
pair_matching イベントのペア(開始・終了)をマッチングさせて未完了を検出 接続の開きっぱなし・未終了のトランザクション検出
etw_classic_sync_target Windows ETW(Event Tracing for Windows)と連携 Windows Performance Analyzer との統合分析

5. デッドロック情報の取得

SQL Server 2012 以降では system_health セッションがデフォルトで有効になっており、 デッドロックグラフ(XML)が自動的に ring_buffer および event_file ターゲットに記録されます。

system_health セッションからデッドロックグラフを取得

T-SQL — デッドロックグラフ取得
-- system_health セッションのリングバッファからデッドロックグラフを取得
SELECT
    xdr.value('@timestamp', 'datetime2') AS deadlock_time,
    xdr.query('.')                        AS deadlock_graph_xml
FROM (
    SELECT CAST(target_data AS XML) AS target_data
    FROM sys.dm_xe_session_targets   t
    JOIN sys.dm_xe_sessions          s
        ON t.event_session_address = s.address
    WHERE s.name   = 'system_health'
      AND t.target_name = 'ring_buffer'
) AS data
CROSS APPLY target_data.nodes('//RingBufferTarget/event[@name="xml_deadlock_report"]') AS xdt(xdr)
ORDER BY deadlock_time DESC;

デッドロック専用 XE セッションの作成

T-SQL — デッドロック専用セッション
CREATE EVENT SESSION [capture_deadlocks] ON SERVER
ADD EVENT sqlserver.xml_deadlock_report
ADD TARGET package0.event_file (
    SET filename = N'C:\XE\deadlocks.xel',
        max_file_size = 100,
        max_rollover_files = 10
)
WITH (MAX_MEMORY = 4096 KB, MAX_DISPATCH_LATENCY = 5 SECONDS);
GO
ALTER EVENT SESSION [capture_deadlocks] ON SERVER STATE = START;

6. 低速クエリのトレース

duration(マイクロ秒)でフィルタすることで、しきい値超えの SQL のみを取得できます。 Oracle の SQL Trace(10046 トレース)に相当します。

T-SQL — 1 秒超の低速 SQL 取得セッション
CREATE EVENT SESSION [capture_slow_queries] ON SERVER
ADD EVENT sqlserver.sql_statement_completed (
    ACTION (
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.plan_handle   -- 実行プランを後から取得するために記録
    )
    WHERE (
        [duration] >= 1000000         -- 1 秒 = 1,000,000 マイクロ秒以上
        AND [sqlserver].[database_name] = N'YourDatabase'
    )
),
ADD EVENT sqlserver.rpc_completed (
    ACTION (
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.session_id
    )
    WHERE ([duration] >= 1000000)
)
ADD TARGET package0.event_file (
    SET filename = N'C:\XE\slow_queries.xel',
        max_file_size = 200,
        max_rollover_files = 5
)
WITH (MAX_MEMORY = 8192 KB, MAX_DISPATCH_LATENCY = 30 SECONDS);
GO
ALTER EVENT SESSION [capture_slow_queries] ON SERVER STATE = START;

event_file ターゲットの内容を T-SQL で読み取る

T-SQL — XEL ファイルの解析
-- XEL ファイルを読み込んで低速クエリを一覧表示
SELECT
    event_data.value('(@timestamp)[1]',          'datetime2') AS event_time,
    event_data.value('(data[@name="duration"]/value)[1]', 'bigint') / 1000 AS duration_ms,
    event_data.value('(data[@name="cpu_time"]/value)[1]', 'bigint') / 1000 AS cpu_ms,
    event_data.value('(data[@name="logical_reads"]/value)[1]', 'bigint')    AS logical_reads,
    event_data.value('(data[@name="physical_reads"]/value)[1]','bigint')    AS physical_reads,
    event_data.value('(action[@name="database_name"]/value)[1]','nvarchar(256)') AS db_name,
    event_data.value('(action[@name="username"]/value)[1]',     'nvarchar(256)') AS username,
    event_data.value('(action[@name="sql_text"]/value)[1]',     'nvarchar(max)') AS sql_text
FROM (
    SELECT CAST(event_data AS XML) AS event_data
    FROM sys.fn_xe_file_target_read_file(
        'C:\XE\slow_queries*.xel', NULL, NULL, NULL
    )
) AS src
ORDER BY duration_ms DESC;

7. system_health セッション — 常時記録の活用

system_health は SQL Server が自動的に起動する組み込み XE セッションです。 追加設定なしで以下の情報が常時記録されており、障害発生後に遡って調査できます。

記録内容イベント名説明
デッドロック xml_deadlock_report デッドロックグラフ XML(被害者・関与者・リソース)
重大エラー error_reported 重大度 20 以上のエラー
メモリ不足 scheduler_monitor_system_health_ring_buffer_recorded メモリプレッシャーや OS ページング情報
セキュリティ security_error_ring_buffer_recorded Kerberos / NTLM 認証エラーなど
接続エラー connectivity_ring_buffer_recorded 接続失敗・タイムアウト情報
💡 system_health のファイルパスを確認する
T-SQL
-- system_health セッションの event_file ターゲットのパスを確認
SELECT
    s.name AS session_name,
    t.target_name,
    CAST(t.target_data AS XML).value(
        '(EventFileTarget/File/@name)[1]', 'nvarchar(500)'
    ) AS file_path
FROM sys.dm_xe_sessions          s
JOIN sys.dm_xe_session_targets   t
    ON s.address = t.event_session_address
WHERE s.name = 'system_health'
  AND t.target_name = 'event_file';

8. SSMS での GUI 操作

SSMS の「管理」→「拡張イベント」→「セッション」ノードから、 セッションの新規作成・開始・停止・ライブデータ監視が可能です。

操作方法
新規セッション作成 「セッション」を右クリック → 「新しいセッション ウィザード」または「新しいセッション」
ライブデータ監視 セッションを右クリック → 「ライブデータの監視」。イベントをリアルタイムに表示
XEL ファイルの表示 SSMS のファイルメニュー → 「開く」→ 「ファイル」で .xel ファイルを直接開くと GUI でイベントを閲覧可能
デッドロックグラフの表示 XEL ファイルを開き、xml_deadlock_report イベントを選択すると、「デッドロック」タブでグラフを視覚化できる

Extended Events活用でよくある誤り

Extended Eventsは高機能ですが、設定ミスで本番パフォーマンスに影響を与えたり、大量ログで解析が困難になることがあります。

誤り/失敗パターン何が起きるか正しい対処/防止策
全イベントを無制限に収集するオーバーヘッドが大きくなり本番のパフォーマンスが低下し、ログファイルも急速に肥大化する必要なイベントに絞り、WHERE句でdatabaseやdurationの条件フィルタを必ず設定して収集量を制限する
セッション定義をテスト環境と本番で同一にするテスト環境より高負荷な本番ではI/Oやメモリ消費が予想外に大きくなりシステムに影響する本番適用前に最大ファイルサイズ・ロールオーバー設定・MAX_DISPATCHを本番負荷に合わせて調整する
XELファイルをSSMSで直接開いて全データを読み込む大きなXELファイルを一括読み込みするとSSMSが固まり、分析ができなくなるsys.fn_xe_file_target_read_file()でT-SQLから時間範囲・イベント種別を絞って分析する

参考・公式ドキュメント