SELECTでパーティション化された列ストアのデッドロックを防ぐ方法


10

SQL Server 2016に3つのクラスター化列ストアインデックス(CCI)テーブルがあります。これらのCCIはすべて、テナントIDに基づいて同じパーティションスキームにあります。最近、一貫性のない方法で、結合からこれらのテーブルへの単純な選択ステートメントでデッドロックが発生しています。デッドロックするクエリの例:

SELECT  TOP 33 r.tenantid
FROM    Table_r r
        INNER JOIN Table_cm cm ON r.MyKey=cm.MyKey 
        INNER JOIN Table_pe pe ON r.MyKey=pe.MyKey 
WHERE   r.TenantId = 69
        AND pe.TenantId = 69
        AND cm.TenantId = 69

エラーメッセージ:

トランザクション(プロセスID 56)は、別のプロセスで汎用の待機可能なオブジェクトリソースでデッドロックされ、デッドロックの犠牲者として選択されました。トランザクションを再実行します。

手がかり:

  • クエリがCCI以外の別のインデックスを使用する場合、デッドロックは発生しません。
  • 3つのテナントフィルターのうち2つを削除しても、デッドロックしません。
  • トップ32以下を選択しても、デッドロックは発生しません。
  • OPTION(MAXDOP 1)を追加しても、デッドロックは発生しません。
  • スクランブルされたPRODレプリカ、PROD読み取り専用セカンダリ、およびPROD自体でこれを再現できます。
  • この動作をDEVまたはINTで再現できません。
  • 3つのテーブル結合すべてにWITH(NOLOCK)を追加すると、依然としてデッドロックが発生します
  • クエリ自体がデッドロックします。他にアクティブなプロセスがない場合はデッドロックします。
  • 並列処理のないクエリプランはデッドロックしない

デッドロックxmlはこちら

PRODバージョン:

Microsoft SQL Server 2016(SP2-CU5)(KB4475776)-13.0.5264.1(X64)Jan 10 2019 18:51:38 Copyright(c)Microsoft Corporation Enterprise Edition(64-bit)on Windows Server 2012 R2 Standard 6.3(Build 9600 :)(ハイパーバイザー)

このクエリのデッドロックを防ぐにはどうすればよいですか?

回答:


8

SQL Server 2016を使用しているので、列ストアインデックスに関連する並列デッドロックの少なくとも1つのパブリックバグ修正があることを言及する価値があります。

[FIX] SQL Server 2016および2017でクラスター化列ストアインデックスに対して並列クエリを実行するとデッドロックが発生する

(おかげデニスRubashkin最初にリンクを提供するため)

これはSP1 CU7の一部としてリリースされました。そのCUに達していない場合は、試してみてください。この修正は、SP2(任意のCU)にも含まれます。

一般に、クエリ内並列処理のデッドロックを修正するための2つのアプローチ:

  • 並列処理を回避する(クエリが並列にならないように調整する、MAXDOPヒントを使用するなど)-これは、Thomas Costersによる他の回答で説明されています
  • SQL Serverに最新のサービスパック/累積アップデートを適用する

2

Intra-Query Parallel Thread Deadlocksに関する次のブログを確認しましたか

SyncPoint私は間違えていないよ場合、リソースは、交流イベントの使用を示します。
デッドロックの参加者を見ると、それらはすべて同じspid(55)およびbatch(0)からのものであるが、異なるスレッドを使用していることがわかります。これは、それらがすべて同じ並列クエリの一部であることを示しており、でクエリを実行するたびにデッドロックが発生しないという事実によって確認されていますMAXDOP 1。クエリ内並列スレッドデッドロックの場合、単一のクエリのスレッドは、最終的に同期オブジェクト(この場合はSyncPoints)を待って互いにデッドロックします。

この種の動作を最後に目にしたとき、クエリをさらに最適化して、クエリが並列実行プランを使用しないようにすることができました。結果セットを32レコードに制限するか、別のインデックスを使用して、同じことをしたと思います。
別のオプションはMAXDOP 1、クエリに追加することですが、このオプションの大ファンではありません。

ただし、これらの2つのオプションをいじる前に、まず最新のSP / CUを使用しているかどうかを確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.