SQL Serverがデフォルトで追跡する貴重な情報がかなりあります。SQL Server 2005以降、バックグラウンドで実行される「デフォルトトレース」があり、SQL Server 2008以降、と呼ばれる拡張イベントセッションが自動的に実行されていsystem_health
ます。
また、SQL Serverエラーログ、SQL Serverエージェントログ、Windowsイベントログ、およびSQL Server監査、管理データウェアハウス、イベント通知、DMLトリガー、DDLトリガー、SCOM / System Centerなどの追加のログから特定の情報を見つけることもできます。、独自のサーバー側トレースまたは拡張イベントセッション、またはサードパーティの監視ソリューション(私の雇用主であるSQL Sentryが作成したソリューションなど)。オプションで、いわゆる「ブラックボックストレース」を有効にして、トラブルシューティングを支援することもできます。
ただし、この投稿では、デフォルトのトレース、拡張イベントセッション、エラーログなど、一般的にどこでも有効になっているものに焦点を当てます。
デフォルトのトレース
デフォルトのトレースは、を使用しsp_configure
て無効にしない限り、通常ほとんどのシステムで実行されています。有効になっている限り、これは貴重な情報の豊富なソースになります。以下に、キャプチャされるトレースイベントを示します。
DECLARE @TraceID INT;
SELECT @TraceID = id FROM sys.traces WHERE is_default = 1;
SELECT t.EventID, e.name as Event_Description
FROM sys.fn_trace_geteventinfo(@TraceID) t
JOIN sys.trace_events e ON t.eventID = e.trace_event_id
GROUP BY t.EventID, e.name;
に参加しsys.trace_columns
てどのイベントにどのデータが付随するかを確認することでより詳細になりますが、特定のイベントのトレースデータを実際にクエリするときに何があるかを見ることができるので、ここではスキップします。これらは私のシステムで利用可能なイベントです(これらが一致することを確認するためにクエリを実行する必要がありますが、これはまだSQL Server 2019 CTP 2.4を介した同じイベントのセットです):
EventID Event_Description
------- ----------------------------------------------
18 Audit Server Starts And Stops
20 Audit Login Failed
22 ErrorLog
46 Object:Created
47 Object:Deleted
55 Hash Warning
69 Sort Warnings
79 Missing Column Statistics
80 Missing Join Predicate
81 Server Memory Change
92 Data File Auto Grow
93 Log File Auto Grow
94 Data File Auto Shrink
95 Log File Auto Shrink
102 Audit Database Scope GDR Event
103 Audit Schema Object GDR Event
104 Audit Addlogin Event
105 Audit Login GDR Event
106 Audit Login Change Property Event
108 Audit Add Login to Server Role Event
109 Audit Add DB User Event
110 Audit Add Member to DB Role Event
111 Audit Add Role Event
115 Audit Backup/Restore Event
116 Audit DBCC Event
117 Audit Change Audit Event
152 Audit Change Database Owner
153 Audit Schema Object Take Ownership Event
155 FT:Crawl Started
156 FT:Crawl Stopped
164 Object:Altered
167 Database Mirroring State Change
175 Audit Server Alter Trace Event
218 Plan Guide Unsuccessful
デフォルトのトレースではロールオーバーファイルが使用されるため、使用可能なデータはこれまでにしか戻らないことに注意してください。使用可能なデータの日付範囲は、上記のイベントの数と取得頻度によって異なります。より長い履歴を保持したい場合は、トレースに関連付けられている現在非アクティブなファイルを定期的にアーカイブするジョブをセットアップできます。
例
質問では、私が見つけたいくつかの質問をしました。デフォルトトレースから特定の情報を取得するためのクエリの例を次に示します。
質問:AdventureWorksデータベースで最後に自動拡張が行われたのはいつでしたか?
このクエリは、ログファイルとデータファイルの両方について、AdventureWorksデータベース内のすべてのAutoGrowイベントをプルしますが、これらはまだデフォルトのトレースログファイルにあります。
DECLARE @path NVARCHAR(260);
SELECT
@path = REVERSE(SUBSTRING(REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT
DatabaseName,
[FileName],
SPID,
Duration,
StartTime,
EndTime,
FileType = CASE EventClass WHEN 92 THEN 'Data' ELSE 'Log' END
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE EventClass IN (92,93)
AND DatabaseName = N'AdventureWorks'
ORDER BY StartTime DESC;
質問:dbo.EmployeeAuditDataテーブルを削除したのはいつですか?
これによりDROP
、という名前のオブジェクトのイベントが返されEmployeeAuditData
ます。DROP
テーブルのイベントのみを検出するようにしたい場合は、フィルターを追加できますObjectType = 8277
(完全なリストはここに記載されています)。サーチスペースを特定のデータベースに制限する場合は、フィルターを追加できますDatabaseName = N'db_name'
。
DECLARE @path NVARCHAR(260);
SELECT
@path = REVERSE(SUBSTRING(REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT
LoginName,
HostName,
StartTime,
ObjectName,
TextData
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE EventClass = 47 -- Object:Deleted
AND EventSubClass = 1
AND ObjectName = N'EmployeeAuditData'
ORDER BY StartTime DESC;
ここには複雑な問題があり、非常に端的なケースですが、とにかく言及するのが賢明だと思いました。複数のスキーマを使用し、複数のスキーマで同じオブジェクト名を使用している場合、これがどのスキーマであるかはわかりません(対応するスキーマがまだ存在しない場合)。UserAがSchemaB.Tablenameをドロップし、UserBがSchemaA.Tablenameをドロップしたという外部ケースがあります。デフォルトのトレースはオブジェクトのスキーマを追跡しません(またTextData
、このイベントに対してキャプチャしません)。ObjectID
トレースに含まれているものは、直接一致する場合には役に立ちません(オブジェクトが削除されて存在しなくなったため)。この場合、出力にその列を含めることは、まだ存在する同じ名前のテーブルのコピーに対して相互参照するのに役立ちますが、システムがこれほど混乱している場合(またはそのようなコピーがすべて削除されている場合)それでも、誰がテーブルのコピーを削除したかを推測する信頼できる方法ではないかもしれません。
拡張イベント
SQL Server 2008のサポート:system_healthセッション(SQLCSSブログ)を、次はあなたがからカリングできるデータのリストであるsystem_health
SQL Server 2008および2008 R2でのセッション:
- 重大度> = 20のエラーが発生したセッションのsql_textおよびsession_id
- 17803、701などの「メモリ」タイプのエラーが発生したセッションのsql_textおよびsession_id(すべてのメモリエラーが重大度> = 20ではないため、これを追加しました)
- 「降伏しない」問題の記録(エラーログでMsg 17883としてこれらを見たことがあります)
- 検出されたデッドロック
- ラッチ(またはその他の興味深いリソース)で15秒以上待機したセッションのコールスタック、sql_text、およびsession_id
- ロックで30秒以上待機したセッションのcallstack、sql_text、およびsession_id
- 「外部」待機または「プリエンプティブ待機」のために長時間待機したセッションのコールスタック、sql_text、およびsession_id。
使用system_healthイベントセッション(MSDN) 、リストは多少のSQL Server 2012に拡大(およびSQL Server 2014用に同じまま)されています。
- 重大度が20以上のエラーが発生したセッションのsql_textおよびsession_id。
- メモリ関連のエラーが発生したセッションのsql_textおよびsession_id。エラーには、17803、701、802、8645、8651、8657、8902が含まれます。
- 降伏しないスケジューラーの問題の記録。(これらはSQL Serverエラーログにエラー17883として表示されます。)
- 検出されたデッドロック。
- ラッチ(またはその他の興味深いリソース)で15秒以上待機したセッションの呼び出しスタック、sql_text、およびsession_id。
- ロックで30秒以上待機したセッションのcallstack、sql_text、およびsession_id。
- プリエンプティブな待機を長時間待機したセッションのcallstack、sql_text、およびsession_id。期間は待機タイプによって異なります。プリエンプティブ待機は、SQL Serverが外部API呼び出しを待機している場所です。
- CLR割り当ておよび仮想割り当てエラーのcallstackおよびsession_id。
- メモリブローカ、スケジューラモニタ、メモリノードOOM、セキュリティ、および接続のring_bufferイベント。
- システムコンポーネントは、sp_server_diagnosticsの結果です。
- scheduler_monitor_system_health_ring_buffer_recordedによって収集されたインスタンスのヘルス。
- CLR割り当てエラー。
- connectivity_ring_buffer_recordedを使用した接続エラー。
- security_error_ring_buffer_recordedを使用したセキュリティエラー。
SQL Server 2016では、さらに2つのイベントがキャプチャされます。
KILL
コマンドを使用してプロセスが強制終了されたとき。
- SQL Serverのシャットダウンが開始されたとき。
(ドキュメントはまだ更新されていませんが、これらの変更点やその他の変更点を発見した方法についてはブログに書きました。)
特定のバージョンに適用されるより暗号化された構成を取得するには、常に次のクエリを直接実行できますが、名前を解釈し、上記のより自然な言語リストに一致するように述語を解析する必要があります。
SELECT e.package, e.event_id, e.name, e.predicate
FROM sys.server_event_session_events AS e
INNER JOIN sys.server_event_sessions AS s
ON e.event_session_id = s.event_session_id
WHERE s.name = N'system_health'
ORDER BY e.package, e.name;
可用性グループを使用している場合、実行中の新しいセッションが2つあります:AlwaysOn_failover
とAlwaysOn_health
。次のクエリを使用して、収集したデータを確認できます。
SELECT s.name, e.package, e.event_id, e.name, e.predicate
FROM sys.server_event_session_events AS e
INNER JOIN sys.server_event_sessions AS s
ON e.event_session_id = s.event_session_id
WHERE s.name LIKE N'AlwaysOn[_]%'
ORDER BY s.name, e.package, e.name;
これらのイベントセッションは、リングバッファターゲットを使用してデータを格納するため、バッファプールやプランキャッシュなど、古いイベントは段階的に廃止されるため、必要な日付範囲からイベントをプルできるとは限りません。
例
私はこの架空の質問を投げかけました。
今日、メモリ関連のエラーがいくつ発生しましたか?
以下は、system_health
セッションからこの情報を引き出すことができるサンプルのクエリです(おそらくあまり効率的ではありません)。
;WITH src(x) AS
(
SELECT y.query('.')
FROM
(
SELECT x = CONVERT(XML, t.target_data)
FROM sys.dm_xe_sessions AS s
INNER JOIN sys.dm_xe_session_targets AS t
ON s.[address] = t.event_session_address
WHERE s.name = N'system_health'
) AS x
CROSS APPLY x.x.nodes('/RingBufferTarget/event') AS y(y)
)
SELECT
x, ts = CONVERT(DATETIME, NULL), err = CONVERT(INT, NULL)
INTO #blat FROM src;
DELETE #blat WHERE x.value('(/event/@name)[1]', 'varchar(255)') <> 'error_reported';
UPDATE #blat SET ts = x.value('(/event/@timestamp)[1]', 'datetime');
UPDATE #blat SET err = x.value('(/event/data/value)[1]', 'int');
SELECT err, number_of_events = COUNT(*)
FROM #blat
WHERE err IN (17803, 701, 802, 8645, 8651, 8657, 8902)
AND ts >= CONVERT(DATE, CURRENT_TIMESTAMP)
GROUP BY err;
DROP TABLE #blat;
(この例は、system_health
セッションに関するAmit Banerjeeの紹介ブログ投稿から大まかに借りています。)
拡張イベントの詳細(特定のデータを照会できる多くの例を含む)については、Jonathan Kehayiasによる次の31部のブログシリーズを参照してください。
https://www.sqlskills.com/blogs/jonathan/an-xevent-a-day-31-days-of-extended-events/
エラーログ
SQL Serverは、デフォルトで現在のプラス6個の最新のエラーログファイルを保持します(ただし、これは変更できます)。スタートアップ情報(使用中のコアの数、メモリ内のロックページが設定されているかどうか、認証モードなど)だけでなく、ドキュメント化するのに十分なエラー(および他の場所でキャプチャされていない)その他のシナリオなど、多くの情報がそこに保存されます。最近の例の1つは、データベースがオフラインになったときに探している人です。これを判断するには、最新の7つのエラーログでテキストをスキャンしますSetting database option OFFLINE
。
EXEC sys.sp_readerrorlog 0,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 1,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 2,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 3,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 4,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 5,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 6,1,'Setting database option OFFLINE';
この最近の回答で他のいくつかの詳細をカバーしました。また、toadworldや公式文書にも良い背景情報があります。
エラーログがデフォルトで追跡する「エラー」の1つのグループ-そして重要な情報を尾からより速く落とすことができる-成功したすべてのバックアップメッセージです。トレースフラグ3226を有効にすることにより、エラーログがノイズでいっぱいになるのを防ぐことができます。