SE の雑記

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

SQL Server と AppDomain

leave a comment

SQL Server と AppDomain の関係について整理する必要があったので、情報を遺しておきたいと思います。

SQL Server は通常の使用を行っていても、一部の機能では、CLR (.NET 共通言語ランタイム) が使用されており、AppDomain が生成されている可能性があります。

アプリケーションドメイン (AppDomain)

アプリケーションドメイン (AppDomain)は、SQL Server ではなく、.NET Framework の用語となります。

アプリケーションドメインについては、上記のドキュメントで次のように記載が行われています。

アプリケーション ドメインは、共通言語ランタイムがアプリケーション間を分離するために使用できる、より安全で柔軟性に富んだ処理単位となります。 個別のプロセスを使用する場合と同じ分離レベルを実現しながら、しかしプロセス間での呼び出しやプロセスの切り替えによるオーバーヘッドを生じることもなく、1 つのプロセス内で複数のアプリケーション ドメインを実行できます。 1 つのプロセス内で複数のアプリケーションを実行できるため、サーバーのスケーラビリティが飛躍的に向上します。

CLR がアプリケーション間を分割するために使用されるという記載があり、この機構が SQL Server 内で CLR が使用されている処理でも使用されています。

 

SQL Server と CLR

SQL Server では、SQL Server の CLR 統合 (SQL CLR) という機能が、SQL Server 2005 から実装されています。

SQL Server 2017 で CLR の厳密なセキュリティ というセキュリティモデルが追加されており、SQL Server のバージョンの進化によって機能追加が行われています。

 

CLR が利用できるものとしては、CLR ユーザー定義関数 / CLR ユーザー定義型 / CLR ストアドプロシージャ / CLR トリガーというような機能があり、SQL Server のこれらの機能を .NET Framework を使用して記述することができます。

並列クエリ処理 で記載されていますが、通常のユーザー定義関数 (CREATE FUNCTION) で関数を記載した場合、並列処理が妨げられる要因となるため、 CLR ユーザー定義関数を使用して、関数を使用しても並列処理が可能とするというような場合にも利用することができます。

 

標準機能と CLR

CLR はユーザーが使用することができますが、それ以外に、SQL Server の標準機能でも利用されています。

有名なものとしては、空間型と階層型のデータ型です。

これらのデータ型は SQL Server のシステム組み込みのデータ型となりますが、CLR で実装が行われています。

そのほかには、FORMAT 関数も CLR が使用されています。

空間型 / 階層型のデータ型については、CLR ユーザー定義型 / FORMAT 関数は CLR ユーザー定義関数がシステム実装のものとして使用されているのかと思います。

空間型 / 階層型で CLR が使用されていることについては、sys.type_assembly_usages から確認することができます。

SELECT * FROM sys.type_assembly_usages AS au
INNER JOIN sys.types AS t ON au.user_type_id = t.user_type_id

 

image

これらのデータ型や関数については初回使用時 (データ型であれば該当の列への初回アクセス時) にアセンブリがロードされるようです。

 

ApDomain の生成状況の確認

CLR が使用された際に、App Domain が生成されます。

SQL Server のプロセスの中で .NET のアセンブリがロードされますので様々な方法で App Domain を確認することができます。

通常の .NET のアプリケーションと同様に Process Explorer で sqlservr.exe の情報を確認することも可能です。

image

SQL Server の DMV では、AppDomain についての情報を確認するためのものが sys.dm_clr_appdomains として提供されています。

この DMV を参照することで AppDomain がどのようになっているのかを確認することができます。(appdomain_name の末尾の数字はインクリメントされていくため、この数字は creation_time の日付を確認すると、頻繁に CLR のアンロード / 再ロードが発生しているかの確認ができたりもします)

image

appdomain_name が「master」や「mssqlsystemresource」で始まっているものについては基本的には、SQL Server のシステムに組み込まれている CLR が利用されているものとなり、ユーザーデータベース名で始まっているものは、ユーザーが作成した CLR になると思います。

この情報を確認することで、AppDomain の生成状況を確認することができ、CLR が利用されているのかの判断を行うことができます。

CLR で使用されているメモリについては、sys.dm_os_memory_clerks の「type=MEMORYCLERK_SQLCLR」で確認することができたりもします。

image

 

AppDomain の情報の他の取得方法

AppDomain の情報については上記の他にもいくつかの確認方法があります。

AppDomain は基本的に、CLR の機能を最初に使用した場合に生成されていますので、SQL Server のサービスを再起動した後に、次のような FORMAT 関数を実行してみると情報の取得がわかりやすいです。

SELECT FORMAT(100,'#,##0')

 

AppDomain が生成されると SQL Server の ERRORLOG に次のようなメッセージが出力されます。

image

メモリが不足し、AppDomain がアンロードされる場合なども上記のようなメッセージに近いものが出力されますので、ERRORLOG を確認することで AppDomain の利用状況を確認できます。

そのほかには、拡張イベントも使用することができます。

CLR のロードについては、「assembly_load」というイベントが用意されており、これで CLR のアセンブリのロード状況を確認することができます。アセンブリがロードされたタイミングで AppDomain が作成されますので、このような情報からも追うことはできるのではないでしょうか。

image

 

最後に

SQL Server の DB 部分だけを触っている場合、.NET Framework の知識が必要ないかというと、今回のような AppDomain 関連では .NET Framework の基本的な考え方についても把握しておく必要が出てきます。

今回は触れていませんが、CDC でも一部の処理は CLR で実装されており、CDC の変更データを検索するための関数 (cdc.fn_cdc_get_all_changes_capture_instance  / cdc.fn_cdc_get_net_changes_capture_instance) も CLR で実装が行われているため、これらの関数の初回アクセス時には、AppDomain が生成されています。

SQL Server の ERRORLOG に AppDomain のメッセージが表示された場合、どのような処理で CLR が使用されているのかを考えてみるということも重要なのではないでしょうか。

Share

Written by Masayuki.Ozawa

2月 20th, 2022 at 10:25 pm

Posted in SQL Server

Tagged with

Leave a Reply