KB2926217 - 修正: データベース ロック アクティビティが増加すると、パフォーマンスの問題が発生するSQL Server

適用先
SQL Server 2012 Enterprise SQL Server 2012 Developer SQL Server 2012 Standard SQL Server 2012 Express SQL Server 2012 Web SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use) SQL Server 2008 Service Pack 3 SQL Server 2008 Developer SQL Server 2008 Enterprise SQL Server 2008 Standard SQL Server 2008 R2 Service Pack 2 SQL Server 2008 R2 Developer SQL Server 2008 R2 Enterprise SQL Server 2008 R2 Standard

既定では、SQL Server 2014 の Service Pack 1 および SQL Server 2012 の Service Pack 3 にはこの修正プログラムが含まれており、修正プログラムを有効にするためにトレース フラグを追加する必要はありません。 「解決方法」セクションの累積的な更新プログラムの 1 つをインストールした後に修正プログラムを有効にするには、スタートアップ パラメーターにトレース フラグ 1236 を追加して Microsoft SQL Server を起動する必要があります。

現象

多くのプロセッサを搭載したコンピューターで Microsoft SQL Server 2014、SQL Server 2012、SQL Server 2008、または SQL Server 2008 R2 のインスタンスを実行しているとします。 特定のデータベースのロックの数 (リソースタイプ = DATABASE) が特定のしきい値を超えると、以下のパフォーマンスの問題が発生します。

  • スピンロック カウントに対してLOCK_HASH値が上昇します。

    注: このスピンロックを監視する方法の詳細については、「詳細」セクションを参照してください。

  • データベース ロックを必要とするクエリまたは操作は、完了までに時間がかかります。 たとえば、次のようなパフォーマンス遅延が発生することがあります。

    • SQL Server ログイン
    • リンク サーバー クエリ
    • sp_reset_connection
    • 取引

注 特定のデータベースでロックの一覧 (リソースの種類 = DATABASE) を見つけるには、「詳細」を参照してください。 しきい値は環境によって異なります。

解決策

累積的な更新プログラムの情報

この問題は、次の SQL Server の累積的な更新プログラムで最初に修正されました。

SQL Server 2008 R2 SP2 の累積的な更新プログラム 13 /en-us/help/2967540

SQL Server 2008 SP3 の累積的な更新プログラム 17 /en-us/help/2958696

SQL Server 2014 用の累積的な更新プログラム 1 /en-us/help/2931693

SQL Server 2012 SP1 の累積的な更新プログラム 9 /en-us/help/2931078

SQL Server 用の累積的な更新プログラムについて

SQL Server 用の新しい累積的な更新プログラムには、以前の累積的な更新プログラムに含まれていたすべての修正プログラムとすべてのセキュリティ修正プログラムが含まれています。 SQL Server の最新の累積的な更新プログラムを確認してください。

      

修正プログラムの情報
 マイクロソフトでは、この問題を修正する修正プログラムを提供しています。 ただし、この修正プログラムは、ここで説明する問題のみを修正することを目的としたものです。 この修正プログラムは、ここで説明する問題が発生しているシステムにのみ適用してください。

修正プログラムがダウンロード可能な場合は、このサポート技術情報の上部に「修正プログラムのダウンロードが利用可能」セクションがあります。 このセクションが表示されていない場合は、Microsoft カスタマー サービス & サポート にリクエストを送信し、修正プログラムを入手してください。

注: 別の問題が発生した場合、またはトラブルシューティングが必要な場合は、別のサービス リクエストを作成しなければならない場合があります。 この特定の修正プログラムの対象とならない追加のサポートに関する質問と問題には、通常のサポート料金が適用されます。 マイクロソフト カスタマー サービス サポートの電話番号一覧を参照、または別のサービス リクエストを作成するには、次のマイクロソフト Web サイトを参照してください。

/contactus/?ws=support 注: [修正プログラムのダウンロードが利用可能] フォームには、修正プログラムを使用できる言語が表示されます。 使用している言語が表示されない場合は、その言語の修正プログラムが存在しないことになります。

状態

Microsoft は、これが "適用対象" セクションに記載されている Microsoft 製品の問題であることを確認しました。

追加情報

アプリケーションが SQL Server に接続するとき、まずデータベース コンテキストが確立されます。 既定では、接続は SH モードで DATABASE ロックの取得を試みます。 SH-DATABASE ロックは、接続が停止されるか、接続の有効期間中にデータベース コンテキストが変更されたときに解放されます。 同じデータベース コンテキストを使用するアクティブな接続が多数ある場合、その特定のデータベースに対して DATABASE リソース タイプのロックを多数設定できます。

16 以上の CPU を持つコンピューターでは、テーブル オブジェクトのみがパーティション化されたロック スキームを使用します。 ただし、データベース ロックはパーティション化されません。 したがって、データベース ロックの数が多いほど、SQL Server がデータベースのロックを取得するのにかかる時間が長くなります。 ほとんどのアプリケーションでは、この設計による問題は発生しません。 ただし、数値が特定のしきい値を超えるとすぐに、ロックを取得するために追加の作業と時間が必要になります。 ロックを追加するごとにマイクロ秒のコストはわずかですが、ロック ハッシュ バケットはスピンロックを使用して保護されるため、合計時間が急速に増加する可能性があります。 これにより、CPU サイクルが追加され、追加のワーカーがロックを取得するのを待機します。

この修正プログラムでは、起動時にトレース フラグ T1236 が有効になっている場合に、データベース ロック パーティション分割が導入されます。 DATABASE ロックをパーティション化することで、ロック・リストの深さが各ローカル・パーティションで管理可能に維持されます。 これにより、DATABASE ロックの取得に使用されるアクセス パスが大幅に最適化されます。

スピンロックLOCK_HASHを監視するには、次のクエリを使用できます。NOCOUNT をオンに設定
CREATE TABLE #spinlock_stats([CaptureTime] datetime,[name] nvarchar(512),[collisions] bigint,
[spins] bigint,[spins_per_collision] real,[sleep_time] bigint,[backoffs] int)
DECLARE @counter int = 1
@counter < 100
      BEGIN
            INSERT INTO #spinlock_stats SELECT GETDATE() as "CaptureTime" , * FROM sys.dm_os_spinlock_stats WHERE [name] = 'LOCK_HASH'
            WAITFOR DELAY '00:00:05'
            SET @counter +=1
      End
SELECT * FROM #spinlock_stats ORDER BY [CaptureTime]
DROP TABLE #spinlock_stats SQL Serverでのスピンロック競合の診断と解決の詳細については、次のドキュメントを参照してください。

SQL Server でのスピンロック競合の診断と解決 注: このドキュメントは SQL Server 2008 R2 向けに書かれていますが、情報は SQL Server 2012 にも適用できます。

参考資料

SQL Server 2012 のトレース フラグの詳細については、次の TechNet Web サイトを参照してください。

SQL Server 2012 のトレース フラグに関する情報
ユーザー/データベースのデータベース ロック数を検索する方法の詳細については、次のクエリを使用してこの値を計算してください:select Resource_database_id、resource_type、request_mode、request_status、
count (*) 'LockCount' from sys.dm_tran_locks
Resource_database_id、resource_type、request_mode、request_statusでグループ化