SQL Server のコールスタック (Call Stack) を確認にはいくつかの方法が利用することができます。
一番詳細な確認としては、WinDbg で確認する方法になるのではないでしょうか。
それ以外には、Windows Performance Analyzer を使用する方法や、
Process Monitor / Process Explorer を使用する方法です。
これ以外の一つが「拡張イベントの Call Stack を SQL Call Stack Resolver を使用して確認する」という方法です。
拡張イベントの Call Stack については、他の方法でも確認することができるのですが、SQL Call Stack Resolver を使用する方法が容易かと思います。
本投稿では、SQL Call Stack Resolver を使用すると、どのように Call Stack が確認できるかを紹介したいと思います。
私は Windows の SQL Server でしか使っていないのですが、SQL Server on Linux (Docker 含む) で取得した拡張イベントに対しても、Call Stack の解決はできていそうでした。
SQL Call Stack Resolver でできること
SQL Call Stack Resolver は、拡張イベントで取得を行った Call Stack の内容を解決するためのツールです。
Microsoft の社員の方が開発されたもので、以前は arvindshmicrosoft/SQLCallStackResolver で公開されていたのですが、Microsoft のリポジトリ (microsoft/SQLCallStackResolver) に管理が移管されたようです。
拡張イベントを取得する際には、各イベントのグローバルフィールドとして「callstack」を取得することができます。
取得した Call Stack については、デフォルトの状態では次のようにアドレスだけが含まれており、内容を表示することはできません。
この Call Stack は SQL Call Stack Resolver を使用すると容易に解析することができます。
SQL Server のシンボルファイルは、パブリックシンボルについては、Microsoft がパブリックに公開しているシンボルサーバーから取得することができますが、特定のバージョンのシンボルファイルをダウンロードする機能も含まれていますので、シンボルファイルも容易に入手することが可能です。
拡張イベントの Call Stack の情報を公開しているもので有名なのは、SQLskills の SQL Server Wait Types Library / SQL Server Latch Classes Library ではないでしょうか。
PAGEIOLATCH_SH であれば、次のような情報が公開されています。
この情報ですが「wait_completed」の拡張イベント、該当の待機事象 (wait_type) でフィルターし、Call Stack を取得したものだと思います。
実際に自分で取得してみた情報がこちらになりますが、似たような呼び出し履歴の構成になっているのではないでしょうか。
この情報はスタックですので、下から上に向かって処理が流れています。
「sqlmin!Bpool::Get」がコールされた後に「sqlmin!BUF::AcquireLatch」以降の処理が実行されていることが確認できますね。
この部分が PAGEIOLATCH_SH の待機が発生する条件となる部分であると Call Stack から推測することができます。
全てがわかりやすい Call Stack になっているとは限りませんが、待機事象と Call Stack の情報の組み合わせについては、相性が良いかと思います。
SQL Server の待機事象の情報は、sys.dm_os_wait_stats (Transact-SQL) / sys.dm_os_latch_stats (Transact-sql) から確認することが多いですが、一部の待機事象については「内部使用のみです。」となっており、詳細が記載されていないものがいくつもあります。
Call Stack を分析することで、「どのような動作によって該当の待機事象が発生したか」の推測につながり、待機事象の動作を追うときに重要な情報となるケースがあります。
SQL Call Stack Resolver の使い方
使い方については、Usage に使用方法の画像を含めて記載されていますので、使い方は難しくありません。
最初に、拡張イベントで Call Stack を取得する SQL Server に接続して、SSMS で次のクエリを実行して情報を取得します。
select name, base_address from sys.dm_os_loaded_modules where name not like '%.rll'
情報を取得したら、SQL Call Stack Resolver (SQLCallStackResolver.exe) を起動して、「INPUT:Specify base addresses or modules」をクリックして開いたウィンドウに、デフォルトで入力されている情報を削除し、SSMS で取得した結果を貼り付けます。(上記のクエリについては、開いたウィンドウ内にも記載されており、ツール内で必要なクエリを確認できます)
次に、「Use public pDBs for a known SQL Server build」をクックし、Call Stack を出力した SQL Server のバージョンを CU レベルで合わせて選択し、「Download PDBs」をクリックして、MS のシンボルサーバーから該当バージョンの SQL Server のパブリックシンボルをダウンロードします。
この機能は、SQL Server の Call Stack の分析に使用する基本的な DLL のシンボルファイルが一括でダウンロードできるので、結構便利です。
これで事前の準備は完了です。
拡張イベントで「callstack」を取得するイベントを作成して、ログが取得できましたら、callstack 内容を表示 (callstack をダブルクリック) して、「すべてコピー」でクリップボードに貼り付けます。
コピーした Call Stack を、SQL Call Stack Resolver の左のテキストエリアに貼り付け、「STEP 3 : Resolve callstacks!」をクリックすることで、シンボルファイルを使用して、Call Stack を分析することができます。
WinDbg を使用した Call Stack の分析については、難易度が高いと思うのですが、SQL Call Stack Resolver を使用した方法については数ステップで実施することができ、作業内容も分かりやすいので、障害対応や、内部動作を把握する際などに活用できるケースがあるのではないでしょうか。
[…] https://blog.engineer-memo.com/2021/07/08/sql-call-stack-resolver-%e3%82%92%e4%bd%bf%e7%94%a8%e3%81%… […]
【後で読みたい!】SQL Call Stack Resolver を使用した SQL Server のコールスタックの分析 | Tak's Bar
11 7月 21 at 00:04