sql >> データベース >  >> RDS >> Sqlserver

SQL Server2014CTP1での優先度の低いロック待機オプションの調査

    SQL Server 2014 CTP1には、オンラインインデックス操作およびパーティションスイッチで使用するための優先度の低いロック待機オプションが導入されています。

    SQL Server 2012 Enterprise Editionでオンラインインデックス管理またはインデックスパーティショニングとパーティションスイッチ操作を利用している場合、これらの操作にはまだいくつかのロック要件があるため、ある時点でDDL操作のブロックが発生する可能性があります。

    説明のために、SQL Server2014CTP1で次の単一パーティションのオンラインインデックスの再構築を実行するとします。

     ALTER INDEX [ClusteredIndex_on_ps_ShipDate]ON[dbo]。[FactInternetSales]REBUILDPARTITION =(37)WITH(ONLINE =ON); 

    そして、拡張イベントと次のセッション定義を使用して、この再構築操作中に取得および解放されたロックを見てみましょう(これはターゲットのないセッションであり、SQL Server Management Studioの[ライブデータの監視]ペインで結果を監視しました)。

     CREATE EVENT SESSION [Online_Index_Rebuild_Locks_Taken] ON SERVER ADD EVENT sqlserver.lock_acquired(WHERE([object_id] =(309576141)))、ADD EVENT sqlserver.lock_released(WHERE([object_id] =(309576141)))WITH(MAX_MEMORY =4096 KB、EVENT_RETENTION_MODE =ALLOW_SINGLE_EVENT_LOSS、MAX_DISPATCH_LATENCY =30 SECONDS、MAX_EVENT_SIZE =0 KB、MEMORY_PARTITION_MODE =NONE、TRACK_CAUSALITY =OFF、STARTUP_STATE =OFF); GO 

    値309576141は、FactInternetSalesテーブルのオブジェクトIDを表します。

    単一パーティションのオンラインインデックスの再構築が完了するまでに56秒かかり、完了後、次のロックの取得と解放のアクティビティが表示されました。


    単一パーティションのオンライン再構築のアクティビティをロックする

    出力からわかるように、再構築はオンライン操作ですが、操作のライフサイクル全体にわたってさまざまなモードでロックを取得する必要があります。理想的には、ロック期間は最小限です(たとえば、タイムスタンプは最初のSCH_Sと同じです。 ロックを取得して解放しました)。ただし、最小限のロックでも、再構築または切り替えられるインデックスに対して実行されているトランザクションによっては、同時実行の問題が発生する可能性があります。

    この投稿の冒頭で、MicrosoftがSQL Server2014CTP1のオンライン操作とパーティション切り替え操作に優先度の低いロック待機オプションを導入したことを説明しました。パーティションスイッチについて、次の操作を実行するとします。

     ALTERTABLE[AdventureWorksDW2012]。[dbo]。[FactInternetSales]SWITCHPARTITION 37TO[AdventureWorksDW2012]。[dbo]。[staging_FactInternetSales];

    この操作で取得および解放されたロックを確認するために、以前に定義した拡張イベントセッションを変更して、該当するオブジェクト(ソーステーブルとターゲットテーブル)を含めました。私は次を見ました:


    パーティション切り替え操作のロックアクティビティ

    空のパーティションへの切り替え操作は1秒未満で発生しましたが、それでもSCH_S およびSCH_M 送信元と宛先の両方で、運用ライフサイクル中にロックが必要でした(309576141はFactInternetSales、398624463はstaging_FactInternetSales)。

    繰り返しになりますが、問題のオブジェクトにアクセスする同時トランザクションがない場合、ロックの期間は非常に短くなる可能性がありますが、これが常に可能であるとは限らないため、オンラインインデックスの再構築とパーティションの切り替え操作が実際にブロックされる可能性があります。

    したがって、この現実に伴い、SQLServer2014ではWAIT_AT_LOW_PRIORITYが導入されています。 MAX_DURATIONで調整できる引数 およびABORT_AFTER_WAIT 両方のALTER INDEXのオプション およびALTER TABLE オンラインインデックス操作とパーティションスイッチ操作の両方に使用できるコマンド。

    これにより、私たちは何ができるようになりますか?まず、SQL Server 2014以前の動作について説明します。例として、次のトランザクションが開いていて、コミットされていないことを想像してみてください。

     BEGIN TRANSACTION;DELETE[dbo]。[staging_FactInternetSales];

    ALTER TABLE SWITCHを実行しようとした場合 別のセッションの宛先としてstaging_FactInternetSalesテーブルに送信すると、ブロックされ、リクエストは待機します。特にこの例では、LCK_M_SCH_Mで待機しています。 待機タイプ。トランザクションをロールバックまたはコミットすると、操作を先に進めて完了することができます。

    SQLServer2014のWAIT_AT_LOW_PRIORITYを使用している場合 MAX_DURATIONを使用 およびABORT_AFTER_WAIT 、アプリケーションの要件に応じて、いくつかの異なるオプションを活用できます。

    MAX_DURATION オンラインインデックスの再構築またはパーティションスイッチ操作が待機する分数を指定できます。 MAX_DURATIONの場合 値に達したら、ABORT_AFTER_WAITの設定に基づいて次に何が起こるかを設定できます 、NONEの値にすることができます 、SELF またはBLOCKERS

    • NONE インデックス操作が引き続き操作を試行することを意味します。
    • SELF これは、MAX_DURATION に達すると、操作(オンラインインデックスの再構築またはパーティションの切り替え)がキャンセルされます。
    • BLOCKERSの場合 を使用すると、オンラインインデックスの再構築またはパーティションスイッチの操作をブロックしているトランザクションがすべて強制終了されます(私の意見では、軽く使用するオプションではありません)。 BLOCKERS ALTER ANY CONNECTIONも必要です オンラインインデックスの再構築またはパーティションスイッチ操作を発行するリクエストの権限。

    次のコード例は、さまざまな構成のバリエーションを示しています。

      2014年以前のデフォルトの動作(無期限に待機)

        以下を実行すると、SQL Server 2014より前の動作に慣れている動作になります。それでも、特定のシナリオで必要または期待される動作になる可能性があります。

         ALTERTABLE[AdventureWorksDW2012]。[dbo]。[FactInternetSales]SWITCHPARTITION 37 TO[AdventureWorksDW2012]。[dbo]。[staging_FactInternetSales]WITH(WAIT_AT_LOW_PRIORITY(MAX_DURATION =0 MINUTES、ABORT_AFTER_WAIT =NONE)); 

      1分間待って、DDL操作をキャンセルします

        次の例では、ブロッキングトランザクションがある場合、1分間待機し、SWITCHに対して「ロック要求のタイムアウト期間を超えました」と表示されます。 最大期間に達した場合の操作:

         ALTERTABLE[AdventureWorksDW2012]。[dbo]。[FactInternetSales]SWITCHPARTITION 37 TO[AdventureWorksDW2012]。[dbo]。[staging_FactInternetSales]WITH(WAIT_AT_LOW_PRIORITY(MAX_DURATION =1 MINUTES、ABORT_AFTER_WAIT =SELF)); 

      1分間待って、ブロッカーを殺します

        この例では、ブロッキングトランザクションがある場合、1分間待機してから、ブロッキングトランザクション(送信元または宛先を含む)を強制終了し、SWITCHを許可します。 操作を完了します。

         ALTERTABLE[AdventureWorksDW2012]。[dbo]。[staging_FactInternetSales]SWITCHPARTITION 37 TO[AdventureWorksDW2012]。[dbo]。[FactInternetSales]WITH(WAIT_AT_LOW_PRIORITY(MAX_DURATION =1 MINUTES、ABORT_AFTER_WAIT =BLOCKERS)); 

        DELETEの私の例では コミットされていないトランザクション内では、アクティブに実行されているステートメントがなかったため、SQL Server Management Studioウィンドウにエラーはありませんでしたが、そのセッション内で別のステートメントを試行すると、次のエラーメッセージが返されました(セッションが強制終了されたため):

        メッセージ233、レベル20、状態0、行3
        サーバーにリクエストを送信するときに、トランスポートレベルのエラーが発生しました。 (プロバイダー:共有メモリプロバイダー、エラー:0 –パイプのもう一方の端にプロセスがありません。)

      ブロッカーをすぐに殺す(SWITCHのソースまたは宛先)

        以下は、ブロッカーをすぐに強制終了する例です。私の例では、切り替えは1秒未満で発生し、実際、ブロッカーであったセッションは強制終了されました。

         ALTERTABLE[AdventureWorksDW2012]。[dbo]。[FactInternetSales]SWITCHPARTITION 37 TO[AdventureWorksDW2012]。[dbo]。[staging_FactInternetSales]WITH(WAIT_AT_LOW_PRIORITY(MAX_DURATION =0 MINUTES、ABORT_AFTER_WAIT =BLOCKERS)); 

    私が言いたかった最後のポジティブな側面…

    SQL Serverエラーログは、ABORT_AFTER_WAITに関する情報を含む、優先度の低いロック待機の使用状況のデフォルトの監査を提供します。 被害者情報に沿った操作:

    日付2013年9月10日午後1時37分15秒
    ログSQLServer(現在– 2013年9月10日午後12時30分)
    ソースspid51
    メッセージ
    プロセスID 57は、database_id =5、object_id=309576141のABORT_AFTER_WAIT=BLOCKERSDDLステートメントによって強制終了されました。

    また、元の操作自体の個別のエントリも表示されます。例:

    ALTER TABLE SWITCHステートメントは、データベース'AdventureWorksDW2012'、テーブル'staging_FactInternetSales'、ホスト名'WIN-4T7S36VMSD9'、ホストプロセスID 1360、ターゲットテーブル'AdventureWorksDW2012.dbo.FactInternetSales'で、MAX_DURATION=1およびABORT_AFTERのWAIT_AT_LOW_PRIORITYオプションを使用して実行されました。ブロック。ユーザーセッションのブロックは、最大待機時間の後に強制終了されます。

    この種のログは、トラブルシューティングと監査の目的で非常に役立ちます。それを見てうれしいです。


    1. LinqtoOracleを使用する方法はありますか

    2. Addnoderesolv.confの失敗

    3. 中括弧とワイルドカードでエスケープするOracleテキスト

    4. PSQLのDECIMALデータ型とNUMERICデータ型の違い