SQLBits 2023 の Bob Ward の SQL Server 2022 hidden gems で紹介されていたのですが、SQL Server 2022 で追加された query_abort という拡張イベントが、今後の SQL Server でエラーの原因を取得する際に活用できそうでしたので情報を残しておこうと思います。
この拡張イベントについては SQL Server 2022 Revealed でも触れられています。
従来の SQL Server でもエラーが発生した拡張イベントを取得することができました。
例としては、sql_batch_completed のイベントで「result <> OK」でフィルターして取得するという方法です。(Error または Abort を取得するようにフィルターすることでも対応できます)
ロック競合によってクエリタイムアウトが発生した場合の sql_batch_completed のイベントを取得すると次のような情報を取得できます。
この情報はクエリタイムアウトが 5 秒で設定されている状態で、ロック競合によりクエリがタイムアウトしたものとなります。どのようなクエリでエラー (Abort) となったのかを確認できます。
情報としてコールスタックを追加していますので、SQLCallStackResolver を使用してコールスタックを解決してみます。
エラーが発生したことは確認できるのですが、「何に起因してエラーが発生したか」までは確認することはできません。
今回は意図的にロック競合を発生させてクエリをタイムアウトさせたので、ロック競合が起因していることはわかるのですが、ログの情報のみで原因を確認するのはこの情報だけでは不足しています。
この不足点を解消するため、SQL Server 2022 では「query_abort」という拡張イベントが追加されました。
この拡張イベントでは次のような情報を取得することができます。
初期状態で取得されるイベントフィールドとして「task_callstack_rva」というコールスタックのフィールドが含まれており、このコールスタックを解決すると次のようになります。
「callstack (or callstack_rva)」とは異なり、実際にエラーが発生した際に実行されていた処理のコールスタックが取得されるため、エラーが発生した直前にどのような処理が行われていたかを確認することができます。
今回取得されているコールスタックから、エラーの直前にはロックによる待機が発生していたことが確認できますので、ロック競合によってエラーとなったということを拡張イベントから確認することができます。
この情報により、今までは他のメトリックや拡張イベントと組み合わせて実施する必要のあったエラー原因の解析が単一の拡張イベントで実施できる可能性が出てきます。
簡単に確認した範囲では拡張イベントによるオーバーヘッドは大きくなさそうでしたが、SQL Server 2022 では拡張イベントによるオーバーヘッドを確認するための、sys.dm_xe_database_session_event という動的管理ビューが追加されており、New In SQL Server 2022 and Azure SQL: XEvent Performance Metrics で解説が行われています。拡張イベント取得によるオーバーヘッドを確認する際にはこの情報も合わせて確認してみるとよいのではないでしょうか。