SharePoint と SQL ブロッキングの話 Part2

<関連記事>

SharePoint と SQL ブロッキングの話 Part1

SharePoint と SQL ブロッキングの話 Part2

SharePoint と SQL ブロッキングの話 Part3

皆さんこんにちは

SharePoint サポートチームの荒川です。

前回に引き続き、SharePoint と SQL ブロッキングの話をします。

ここから先はさらに詳しい解説となります。Community Open Day の限られた時間内に収められなかった部分でもありますので、技術的により深い内容を得たい方はご参考いただければ幸いです。

■どのようなシナリオでブロッキングが発生し得るのか

私が手元で再現して実際に動作を確認しのは、以下のパターンです。先述の Community Open Day セッションのデモでもこちらの例を使用しています。

・大量のアイテムが格納されているライブラリの親フォルダ名の変更

・大量のアイテムを含むサイトデータのごみ箱からの削除

上記以外に、過去のユーザー事例から、以下のような状況でもブロッキングが発生する可能性があることを確認しています。詳細な条件等は残念ながら確認できておらず、点在する情報からの判断となります。

・ワークフローによる大量のアイテム更新

・大量のコンテンツに複雑な権限を付与した環境での権限の継承、切断

■ブロッキングの有無を確認する方法

実際に問題が起きた後で、ブロッキングの有無を確認する方法はあるのでしょうか?

答えとしては、ありません。残念ながら既に問題が起きた後、ブロッキングが原因でサイトの応答が停止していたことを断定する手段は無いのです。

したがって、問題を特定するには、サイトの応答が停止している時、つまり SQL Server でブロッキングが起きている最中に、SQL Server 側で利用状況モニターを確認する必要があります。

利用状況モニターの詳細な解説についてはここでは触れませんが、簡単な確認方法を参考まで、紹介しておきます。(利用状況モニターの詳細について知りたい方は SQL Server の Books オンラインやヘルプ ドキュメントをご参照ください。)

今回は SQL Server 2005 の例で説明しますが SQL Server 2008 でも同様の方法で確認できます。

まず、ブロッキングが発生している際に利用状況モニターを起動して、ブロッキングカラムでソートすると、以下のような情報が参照できます。

上記の例では、ブロックチェーンの先頭ブロックが SPID 58 の処理であることがわかります。この処理の内容を見てみましょう。

Management Studio で以下のクエリを実行します。

DBCC INPUTBUFFER(58)

EventInfo の内容を確認すると、以下のような情報が得られました。

(@P1 uniqueidentifier,@P2 uniqueidentifier,@P3 nvarchar(31),@P4 nvarchar(32),@P5 int,@P6 int,@P7 int,@P8 int,@P9 int,@P10 int,@P11 bit OUTPUT,@P12 nvarchar(259) OUTPUT,@P13 int,@P14 uniqueidentifier,@P15 nvarchar(23),@P16 nvarchar(8),@P17 uniqueidentifier OUTPUT,@P18 int OUTPUT,@P19 int OUTPUT,@P20 int OUTPUT,@P21 int OUTPUT)DECLARE @@iRet int; BEGIN TRAN; EXEC @@iRet = proc_RenameUrl @P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11 OUTPUT, @P12 OUTPUT;EXEC proc_GetAuditMaskOutput @P13, @P14, @P15, @P16, @P17 OUTPUT, @P18 OUTPUT, @P19 OUTPUT, @P20 OUTPUT; done: IF @@iRet = 0 COMMIT ELSE ROLLBACK SET @P21=@@iRet;

詳細なことは直ぐにはわかりませんが、内容からヒントになる情報が得られることもあります。実は、今回は大量のコンテンツが存在するライブラリのフォルダをリネームするというオペレーションを実施して、意図的にブロッキングを発生させました。フォルダ名が変わると、AllDocs というユーザーデータ テーブルのエントリが持つ URL カラムの内容を書き換える必要が生じるため、レコード数が多いとロックエスカレーションが発生します。

次に、同様にブロッキングの影響を受けている SPID 91 の処理の内容を見てみましょう。

WSS_Content_80.dbo.proc_FetchDocForHttpGet;1

皆さんには馴染みが薄いと思いますが、我々 SharePoint のサポートエンジニアにとって、このストアドプロシージャ proc_FetchDocForHttpGet は頻繁に目にするものです。

このストアドプロシージャは、主に AllDocs テーブルから SharePoint コンテンツの情報を取得するために使用されます。

これらの結果より、AllDocs テーブルのレコードに対する INSERT コマンドがブロッキングを引き起こし、恐らく後続の処理であるサイトの閲覧を阻害しているであろうことが推測できます。

それでは、さらに高度な分析をしてみましょう。例えば、Web サーバーが複数存在する環境において、また、Web アプリケーションが複数存在する環境において、いったいどの Web サーバーのどのサイトからの通信がブロッキングを引き起こしているのでしょうか。

Management Studio で master データベースに対して以下のクエリを実行してみましょう。

SELECT hostname,program_name,hostprocess FROM sysprocesses WHERE spid = 58

上記のクエリ結果から、ホスト名が MOSS、プロセス ID 552 のプロセスからの通信であることが特定できます。

では、サーバー MOSS でプロセス ID 552 のプロセスを見てみましょう。

PID 552 は、IIS のワーカープロセス (w3wp.exe) であることが特定できました。

さらに追跡します。

Windows 2003 の場合、%SystemRoot%\system32 ディレクトリに移動し、以下のコマンドを実行します。

>cscript iisapp.vbs

※Windows 2008 以降では、%SystemRoot%\system32\inetsrv ディレクトリに移動し、以下のコマンドを実行します

>appcmd list wp

コマンドが成功すると以下のようにアプリケーションプールに紐づけられたプロセス ID の結果が出力されます。

例)

W3WP.exe PID: 552 AppPoolId: SharePoint - 80

W3WP.exe PID: 2684 AppPoolId: SharePoint Central Administration v3

W3WP.exe PID: 3048 AppPoolId: SharePoint – 9000

この結果から、アプリケーションプール「SharePoint - 80」で実行されている Web アプリケーションからの処理が原因となっていることが特定できました。

上記の例において何よりも問題の解決を優先される場合には、Web フロントエンドサーバー MOSS のアプリケーション プール「SharePoint - 80」を強制的にリサイクルするか、IIS リセットすることで処理を中断し、SQL Server 側で実行中の処理をロールバックすることができます。この場合、当然アプリケーション側の処理であるフォルダのリネーム処理は失敗することになります。

(Part 3 に続く)