アプリケーションの応答が遅くなる理由はたくさんありますが、ユーザーがパフォーマンスについて不満を言っている場合は、SQLServerのデッドロックに対処している可能性があります。幸い、SQL Serverのデッドロックを特定して修正し、アプリケーションのパフォーマンスに悪影響を与えないようにする方法があります。
SQL Serverのデッドロックは、基本的に、同じリソースへの排他的アクセスをめぐって競合している2つのプロセス間のスタンドオフです。一度に1つのプロセスのみがリソースを使用できるため、デッドロックが解決されるまでパフォーマンスが低下します。
注意すべきSQLServerのデッドロックには、変換ロックとサイクルロックの2種類があります。
変換ロックのデッドロックは、スレッドが1つの排他的タイプから別の排他的タイプにロックを変換しようとしたが、最初のスレッドが変換しようとしているリソースに対して別のスレッドがすでに共有ロックを保持しているために発生しません。
SQL Serverには、次の3種類の変換ロックがあります。
- Intent Exclusive(SIX)で共有:このロックは、共有ロックを保持するトランザクションが一部のページまたは行にも排他ロックを持っている場合に発生します。
- Shared with intent update(SIU):このロックは、共有ロックを保持するトランザクションの一部のページまたは行が更新ロックでロックされている場合に発生します。
- インテントエクスクルーシブによる更新(UIX):このロックは、更新ロックを保持するトランザクションが一部のページまたは行にも排他ロックを持っている場合に発生します。
サイクルロックは、2つのプロセスが他のプロセスによってロックされているリソースの排他的ロックを争うことによって引き起こされるSQLServerのデッドロックです。
たとえば、プロセス1は、プロセス2がリソース2のロックを解放するのを待っている間、リソース1のロックを保持しています。プロセス1がリソース1を解放するのを待っている間、プロセス2がリソース2のロックを保持している場合、サイクルロックのデッドロック。
SQLServerのデッドロックを診断する方法
SQL Serverのデッドロックは、アプリケーションでパフォーマンスの問題が発生する可能性のある数十の理由の1つにすぎません。通常は高速で実行されるクエリが突然遅くなる場合は、デッドロックが発生している可能性があります。しかし、何か他のことが起こっている可能性もあります。
したがって、クエリ速度の低下に気付く以外に、デッドロックがデータベースのパフォーマンスの問題の原因であるかどうかをどのように判断しますか?
デッドロックを特定する最も簡単で確実な方法は、1205エラーメッセージの存在です。
トランザクション(プロセスID%d)は、別のプロセスで%。* lsリソースでデッドロックされ、デッドロックの犠牲者として選択されました。トランザクションを再実行します。
1205エラーメッセージは、文字通り、デッドロックとその修正方法を示しています。ただし、Jeremiah Peschkaが指摘しているように、デッドロックの原因を修正していない場合、トランザクションの再実行はおそらく失敗します。
デッドロックを見つけるための別のオプションは、拡張イベントからSQLServerデッドロックグラフを引き出すことです。拡張イベントを介してデッドロックを抽出すると、デッドロックXMLを確認できます。これにより、デッドロックグラフのグラフィック表現よりも多くの情報が提供されます。
デッドロックXMLは、被害者リスト、プロセスリスト、およびリソースリストによって編成されます。各セクションでは、デッドロックに関係する被害者、プロセス、およびリソースについて詳細に説明しているため、問題のトラブルシューティングと解決が容易になります。
SQLServerのデッドロックを修正する方法
SQL Serverのデッドロックを解決する唯一の方法は、プロセスの1つを終了し、ロックされたリソースを解放して、プロセスを完了できるようにすることです。これは、SQL Serverがデッドロックを検出し、競合するプロセスの1つ(つまり、犠牲者)を強制終了したときに自動的に発生します。
SQL Serverは通常、強制終了する接続をランダムに選択しますが、デッドロックの優先順位を設定して、デッドロック中に強制終了する接続を決定することもできます。 2つの接続の優先度設定が異なる場合、SQLServerは最も低い優先度のトランザクションを強制終了します。
SQLServerのデッドロックを防ぐ方法
SQL Serverのデッドロックは、ビジー状態のデータベースを管理している場合の現実です。ただし、DBAは、いくつかの予防策を講じることで、デッドロックの発生を減らし、データベースパフォーマンスへの影響を最小限に抑えることができます。
- より良いインデックスを作成する
- トランザクションの優先順位を調整する
- 試行/再試行モデルを制定する
- 分離モードを変更する
- ロックをできるだけ短時間保持します
- 毎回同じ順序でリソースにアクセスする
- 必要な情報がすべて揃うまで、取引を送信しないでください
- ロックのエスカレーションを制限する
SQL Serverのデッドロックを完全に防ぐことはできませんが、これらのベストプラクティスを実装し、デッドロックの最も一般的な原因のいくつかを事前に回避して、トランザクションの円滑な流れを維持し、データベースのパフォーマンスを最適化することができます。