web-dev-qa-db-ja.com

SQL Server:ロック通信バッファーリソースでデッドロック

このデッドロックタイプの考えられる理由は何ですか? (一般的にデッドロックではありません)

通信バッファリソースをロックする

このシステムはメモリが少なく、バッファ数が制限を超えていますか?

詳細なエラー:

トランザクション(プロセスID 59)は、別のプロセスとのロック通信バッファーリソースでデッドロックされ、デッドロックの犠牲者として選択されました。トランザクションを再実行します

32
usman shaheen

一般的に見られる完全なメッセージ:

トランザクション(プロセスID 53)がロック時にデッドロックしました|別のプロセスとの通信バッファーリソースであり、デッドロックの犠牲者として選択されています。トランザクションを再実行します。

このロックタイプは、SQL Serverが並列として実行したデッドロッククエリでよく見られ、「クエリ内並列デッドロック」と呼ばれることもあります。これは、システムリソースが低いことを指摘するいくつかのステートメントを見たことがありますが、これは少し関与している可能性があります。

並列デッドロックであるかどうかを判断するために気付いた一般的なガイドラインは、XMLデッドロックグラフ(2008年以降のsystem_healthセッションで実行できます)をプルするときです。異なるプロセスIDが同じコードのビットを示しています。実行スタック。

同様に、デッドロックグラフのリソースリストを見て、ウェイターイベントのタイプを確認します。彼らは最も一般的に「e_xxxxxx」、またはこのようなものをおそらく表示します:

<waiter-list>
 <waiter event="e_waitPipeGetRow" type="consumer" id="process821d828" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process8209198" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process3827c18" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process3809eb8" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process8226b08" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process9acb6d8" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process6188d7828" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process381cef8" />
</waiter-list>

この問題を解決するために、さまざまな方法がオンラインおよび書籍で提供されています。私は通常、クエリ/プロシージャの実行プランから見て、並列実行を示している領域に焦点を当てます。次に、最初にクエリを調整しようと試み、最後に最後の手段としてクエリヒントの使用を開始します。

これらのデッドロックを解決するために言及される最も一般的なクエリヒントは、MAXDOP 1の実装です。ただし、その前に、サーバーレベルのMAXDOPおよびコストのしきい値が何に設定されているかを確認することもできます。 Cost Thresholdは通常、デフォルトで5に設定されています。問題のクエリがコードのそのセクションに対して低コストである場合、並列実行する必要がない可能性があるため、最初は35または40に増やします。 MAXDOPクエリヒントを使用するのは好きではありませんが、その場所や目的がないということではありません。私の意見だけ。

28
user507