SE の雑記

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

Azure AD ユーザーでデータベースメールを使用する際のトラブルシューティングに必要なメッセージの取得

leave a comment

SQL Server 2022 / Azure SQL Managed Instance では、Azure Active Directory ユーザーを使用した認証を実施することができます。

設定をする際には、最初の管理者アカウントを設定する必要がありますが、このアカウントには Azure Active Directory グループを指定することもできますので、最初の管理者にはグループを追加し、以降はグループのメンバーをメンテナンスすることで管理者を設定する運用も可能となっています。

このような「Azure Active Directory のグループを介してメンバーに権限を付与する」場合、データベースメールの利用にはいくつか気を付ける点がありますので、それをまとめておきたい思います。

Managed Instance で問題が発生している場合、同様の設定をした SQL Server 2022 でも問題が発生する可能性が高いので、デバッグにしては様々な情報を取得できる SQL Server 2022 のほうが容易かもしれません。

関連するドキュメント

関連するドキュメントとしては次のようなものがあります。

  • sp_send_dbmail (Transact-SQL)
    • パラメーターを使用 @query する場合、実行 sp_send_dbmail するユーザーは SQL ログインであるか、Azure AD または AD のプリンシパル (ログイン) に直接マップされている必要があります。 ユーザーが Azure AD グループまたは AD グループのメンバーである場合、クエリを実行することはできません。 これは、偽装と EXECUTE AS の制限Azure SQL Managed Instanceが原因です
  • SQL Server と Azure SQL Managed Instance での T-SQL の相違点
    • SQL Agent ジョブを作成、変更、実行するために、ユーザーは Azure AD サーバー プリンシパル (ログイン) に直接マップされる必要があります。 直接マップされていないユーザー (たとえば、SQL Agent ジョブを作成、変更、または実行する権利を持つ Azure AD グループに属しているユーザー) は、これらの操作を実質的に実行できません。 これは、SQL Managed Instance の借用と EXECUTE AS の制限事項のためです。

 

データベースメールを使用する際には「msdb.dbo.sp_send_dbmail」ストアドプロシージャを使用します。
単体でクエリから実行することもありますが、定期的にメールを送信したい場合は SQL Agent ジョブをスケジューラーとして使用することもありますので、この二つの情報を確認する必要が出てきます。

これらの機能のドキュメントには、Azure Active Directory のユーザーを使用する際の注意点が記載されており、グループのメンバーとして権限を付与している場合の機能制限が記載されています。

基本的には、

  • グループのメンバーとして権限が付与されている場合、メール送信時にエラーが発生するケースがある
  • エラーが発生した場合、メンバーを介して権限を付与されていても、明示的にログインを作成し、ログインがマッピングされたログインにする必要がある

となるのですが、これを満たしていない場合、sp_send_dbmail 実行時に次のエラーが発生します。

メッセージ 22050、レベル 16、状態 1、行 5
エラー番号 -2147467259 を使用して sqlcmd ライブラリを初期化できませんでした。

 

メッセージ 22050、レベル 16、状態 1、行 12
Failed to initialize sqlcmd library with error number -2147467259.

これらのエラーが発生した場合、権限関連でエラーが発生している可能性が高いのですが、詳細については sp_send_dbmail でラップされてしまっているため、メッセージだけでは根本原因を判断することが難しい可能性があります。

 

エラー発生時のトラブルシューティングにつながるメッセージの取得

sp_send_dbmail 実行時にエラーが発生すると上述のメッセージにラップされてしまっており、根本原因を取得することができないケースがあります。

そのような場合、拡張イベント (または、SQL プロファイラー) のエラー情報の情報を取得することで、根本原因を判断するためのエラー情報を取得できる可能性があります。

実際に取得したものが次の画像となります。

 

image

sp_send_dbmail の実行時にエラーが発生し、クエリを実行したセッションのエラーとしては sqlcmd ライブラリの初期化のエラーとなっています。

しかし、実際には、sp_send_dbmail の @query パラメーターに指定しているクエリの実行でエラーになっており、そのエラーについては拡張イベントの「error_reported」から確認ができます

今回使用した拡張イベントは次のような設定となります。

CREATE EVENT SESSION [error_reported] ON SERVER 
ADD EVENT sqlserver.error_reported(
    ACTION(package0.callstack,sqlserver.session_id,sqlserver.sql_text)
    WHERE ([package0].[greater_than_equal_int64]([severity],(11))))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO


 

sqlcmd ライブラリの初期化のエラーが発生した場合、根本原因は別のエラーかもしれません。

そのエラーについてはクエリを実行したセッションからではなく、インスタンス側のエラーを検出する仕組みを活用することで問題解決につながるメッセージを確認できる可能性があります。

Written by Masayuki.Ozawa

3月 5th, 2023 at 4:49 pm

Leave a Reply

Share via
Copy link
Powered by Social Snap