SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

PowerShell で Microsoft.Data.SqlClient のイベントトレースを取得する

leave a comment

System.Data.SqlClient のイベントトレースについては BID (Built-In Diagnostics) トレースで実装されていたため、BID トレースの設定を有効化する必要があったかと思います。
BID トレースについては次のドキュメントで解説が行われています。

最新の SQL Server のデータプロバイダーである、Microsoft.Data.SqlClient では、イベントトレースの取得方法が BID から、EventSoure からのイベントの取得に変わっているようです。

有効化の方法については、SqlClient でのイベントのトレースの有効化 で記載されていますが、C# であれば、ドキュメントに記載されている方法でトレースを取得することができます。

PowerShell (7.0.2) で Microsoft.Data.SqlClient 2.0 を使用する の Windows PowerShell についての記述を追加していて、PowerShell で Microsoft.Data.SqlClient を実行した場合にもトレースが取得できるのかが気になったので試してみました。

今回、コネクションプールの調査でイベントトレースを使用していたのですが、System.Data と Microsoft.Data のイベントトレースの出力の違いについては、次のソースを確認してみても良いのではないでしょうか。

PowerShell で Microsoft.Data.SqlClient のトレースを取得する

PowerShell は 5.0 以降でクラスをサポートしていますので、SqlClient でのイベントのトレースの有効化 の C# のコードを参考にしながら PowerShell でスクリプトを作成してみます。

using namespace System.Diagnostics.Tracing;

$ErrorActionPreference = "Stop"

class SqlClientListener : EventListener
{
    [void]OnEventSourceCreated([EventSource]$eventSource){
        if($eventSource.Name -eq "Microsoft.Data.SqlClient.EventSource"){
            $this.EnableEvents($eventSource, [EventLevel]::Verbose, [EventKeywords](32+64))
        }
    }
    [void]OnEventWritten([EventWrittenEventArgs]$eventData){
        Write-Host ("{0} : {1}" -f (Get-Date), $eventData.Payload[0])
    }
    
}

Add-type -Path "C:\SqlClient\microsoft.identity.client.4.21.1.nupkg\lib\net461\Microsoft.Identity.Client.dll"
Add-Type -Path "C:\SqlClient\microsoft.data.sqlclient.2.1.2.nupkg\runtimes\win\lib\net46\Microsoft.Data.SqlClient.dll"


$listner = New-Object SqlClientListener

try{
    $conString = "xxxxxxxxxxxxxxxxx"
    $con = New-Object Microsoft.Data.SqlClient.SqlConnection($conString)
    Write-Host "===== Open Connection #1 ========="
    $con.Open()

    $cmd = $con.CreateCommand()
    $cmd.CommandText = "SELECT @@servername"
    $cmd.ExecuteScalar()

    Write-Host "===== Close Connection #1 ========="
    $con.Close()
}catch{
    Write-Host $_.Exception.Message
}finally{
    $con.Dispose()
    $listner.Dispose()
}

$conString については、適切な接続文字列を指定し、Add-Type で読み込んでいる DLL については、適切な場所にダウンロードしたものを使用します。

今回は、コネクションプールの情報を取得するようにしていますので、EventKeywords については、PoolerTrace / PoolerScope を有効にしています。

スクリプトを実行すると、初回実行時には次のような出力を取得することができます。

image

コネクションプールを使用した場合、初回の接続時には、プール内に利用可能な接続がありませんので、接続を作成し、クローズしたタイミングで、プールに接続を Push していることが確認できますね。

2 回目の実行で、コネクションプール内に利用可能な接続がプールされている場合は、次のような実行結果となります。

image

初回実行時と異なり、「Creating new Connection」を実行せずに「Popped from general pool」で、プール内から接続を取得していることが確認できます。

イベントトレースを使用すると、コネクションプール内の接続が、SQL Server から切断されている場合に、どのようにな動作になっているのかを確認することもできます。(プールから切断されている接続を削除して再度作成するという動作が行われていることがトレースから確認できます)

image

 

ADO.NET のコネクションプール (接続プール) については、SQL Server の接続プール (ADO.NET) で解説が行われていますが、イベントトレースの情報とコネクションプールの情報を組み合わせると、プールの動作を理解する一助になるのではないでしょうか。

Share

Written by Masayuki.Ozawa

5月 17th, 2021 at 10:44 pm

Posted in PowerShell,SQL Server

Tagged with ,

Leave a Reply