PART 04 — Extended Events による取得とセクション定義
Extended Events(XE)は SQL Server 標準の軽量イベントトレースフレームワークです。 SQL Profiler の後継として推奨されており、SQL 実行・待機イベント・デッドロック・ エラーなどを低オーバーヘッドで取得できます。 Oracle の Diagnostics Pack の ASH(Active Session History)や Event Monitor に相当します。
1. Extended Events の概要とアーキテクチャ
Extended Events は「セッション」単位でイベントを定義します。 各セッションには イベント(何を取得するか)・ アクション(取得時に付加する情報)・ ターゲット(取得したデータをどこに出力するか)を設定します。
SQL Server Profiler は将来のバージョンで削除予定のため、新規のトレース設計では Extended Events の使用が Microsoft によって推奨されています。 Profiler に比べてオーバーヘッドが大幅に低い(約 2〜3%)という特徴があります。
2. セッションの作成と管理
セッションの基本構文
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 セッションからデッドロックグラフを取得
-- 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 セッションの作成
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 トレース)に相当します。
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 で読み取る
-- 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 セッションの 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 イベントを選択すると、「デッドロック」タブでグラフを視覚化できる |