メモリ最適化 tempdb メタデータ (HkTempDB) のメモリ不足エラー

この記事では、メモリ最適化 tempdb メタデータ機能に関連するメモリ不足の問題をトラブルシューティングするための解決策について説明します。

現象

メモリ最適化tempdbメタデータ (HkTempDB) 機能を有効にすると、割り当てとSQL Serverサービスのクラッシュに対tempdbするメモリ不足の例外を示すエラー 701 が表示されることがあります。 さらに、In-Memory OLTP (Hekaton) のメモリ クラーク MEMORYCLERK_XTP が徐々にまたは急速に成長しており、縮小しないことがわかります。 XTP メモリが上限なしで大きくなると、SQL Serverに次のエラー メッセージが表示されます。

リソース プール 'default' 内のメモリ不足のため、データベース 'tempdb' のページ割り当てを許可しません。 詳細については、'http://go.microsoft.com/fwlink/?LinkId=510837' を参照してください。

DMVdm_os_memory_clerksでクエリを実行すると、メモリ の書き込み担当者MEMORYCLERK_XTPに割り当てられたページメモリが高いことがわかります。 例:

SELECT type, memory_node_id, pages_kb 
FROM sys.dm_os_memory_clerks
WHERE type = 'MEMORYCLERK_XTP'

結果:

type                    memory_node_id                     pages_kb
------------------------------------------------------------ -------------- --------------------
MEMORYCLERK_XTP         0                                  60104496
MEMORYCLERK_XTP         64                                 0

問題を診断する

問題を診断するためにデータを収集するには、次の手順に従います。

  1. 軽量トレースまたは拡張イベント (XEvent) を収集してワークロードを理解 tempdb し、ワークロードに一時テーブルの DDL ステートメントを使用して実行時間の長い明示的なトランザクションがあるかどうかを確認します。

  2. 次の DMV の出力を収集して、さらに分析します。

    SELECT * FROM sys.dm_os_memory_clerks
    SELECT * FROM sys.dm_exec_requests
    SELECT * FROM sys.dm_exec_sessions
    
    -- from tempdb
    SELECT * FROM tempdb.sys.dm_xtp_system_memory_consumers 
    SELECT * FROM tempdb.sys.dm_db_xtp_memory_consumers
    
    SELECT * FROM tempdb.sys.dm_xtp_transaction_stats
    SELECT * FROM tempdb.sys.dm_xtp_gc_queue_stats
    SELECT * FROM tempdb.sys.dm_db_xtp_object_stats
    
    SELECT * FROM tempdb.sys.dm_db_xtp_transactions
    SELECT * FROM tempdb.sys.dm_tran_session_transactions
    SELECT * FROM tempdb.sys.dm_tran_database_transactions
    SELECT * FROM tempdb.sys.dm_tran_active_transactions
    

原因と解決策

DMV を使用して原因を確認すると、問題のさまざまなシナリオが表示される場合があります。 これらのシナリオは、次の 2 つのカテゴリに分けることができます。 この問題を解決するには、シナリオごとに対応する解決策を使用できます。 問題を軽減する方法の詳細については、「メモリ最適化 tempdb メタデータ メモリをチェックに保持するための軽減手順」を参照してください。

XTP メモリ消費量の段階的な増加

  • シナリオ 1

    DMV tempdb.sys.dm_xtp_system_memory_consumers または tempdb.sys.dm_db_xtp_memory_consumers は、割り当てられたバイトと使用されるバイトの大きな違いを示します。

    解決策: この問題を解決するには、SQL Server 2019 CU13、SQL Server 2022CU1、またはそれ以降のバージョンで、割り当てられたが未使用のバイトを解放するための新しいプロシージャsys.sp_xtp_force_gcを持つ次のコマンドを実行できます。

    注:

    SQL Server 2022 CU1 以降では、ストアド プロシージャを 1 回だけ実行する必要があります。

    /* Yes, 2 times for both*/
    EXEC sys.sp_xtp_force_gc 'tempdb'
    GO
    EXEC sys.sp_xtp_force_gc 'tempdb'
    GO
    EXEC sys.sp_xtp_force_gc
    GO
    EXEC sys.sp_xtp_force_gc
    
  • シナリオ 2

    DMV tempdb.sys.dm_xtp_system_memory_consumers は、メモリ コンシューマーの種類 VARHEAP と に割り当てられたバイトと使用されるバイトの高い値を LOOKASIDE示します。

    解決策: 一時テーブルの DDL ステートメントに関連する実行時間の長い明示的なトランザクションを確認し、トランザクションを短くしてアプリケーション側から解決します。

    注:

    テスト環境でこの問題を再現するには、一時テーブルでデータ定義言語 (DDL) ステートメントを使用して明示的な トランザクション を作成し、他のアクティビティが発生したときに長い間開いたままにすることができます。

  • シナリオ 3

    DMV tempdb.sys.dm_db_xtp_memory_consumers は、ラージ オブジェクト (LOB) アロケーターまたはテーブル ヒープ内の割り当て済みバイトと使用済みバイトの高い値を示します。、 Index_IDObject_IDXTP_Object_IDNULLです。

    解決策: 問題の14535149 SQL Server 2019 CU16 を適用します。

  • シナリオ 4

    "VARHEAP\Storage 内部ヒープ" XTP データベース メモリ コンシューマーが継続的に増加すると、メモリ不足エラー 41805 が発生します。

    解決策: 14087445 SQL Server17 CU25 以降のバージョンで既に特定および解決されている問題は、2019 年SQL Serverに移植される予定です。

XTP メモリ消費量の急激なスパイクまたは急激な増加

  • シナリオ 5

    DMV tempdb.sys.dm_db_xtp_memory_consumers は、 ではないNULLテーブル ヒープ内の割り当て済みバイトまたは使用済みバイトの高い値をObject_ID示します。 この問題の最も一般的な原因は、一時テーブルで DDL ステートメントを使用して実行時間が長く、明示的に開かれたトランザクションです。 例:

    BEGIN TRAN
        CREATE TABLE #T(sn int)
        …
        …
    COMMIT
    

    一時テーブルの DDL ステートメントを使用して明示的に開かれたトランザクションでは、メタデータを使用 tempdb して後続のトランザクションに対してテーブル ヒープとルックアサイド ヒープを解放することはできません。

    解決策: 一時テーブルの DDL ステートメントに関連する実行時間の長い明示的なトランザクションを確認し、トランザクションを短くしてアプリケーション側から解決します。

メモリ最適化 tempdb メタデータ メモリをチェックに保持するための軽減手順

  1. 一時テーブルで DDL ステートメントを使用する実行時間の長いトランザクションを回避または解決するには、一般的なガイダンスとしてトランザクションを短くします。

  2. 最大サーバー メモリを増やして、tempdb 負荷の高いワークロードが存在する場合に十分なメモリを動作させることができます。

  3. 定期的に実行 sys.sp_xtp_force_gc します。

  4. メモリ不足の可能性からサーバーを保護するには、tempdb を Resource Governor リソース プールにバインドします。 たとえば、 を使用してリソース プールを MAX_MEMORY_PERCENT = 30作成します。 次に、次の ALTER SERVER CONFIGURATION コマンドを使用して、リソース プールをメモリ最適化 tempdb メタデータにバインドします。

    ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON (RESOURCE_POOL = '<PoolName>');
    

    この変更では、メモリ最適化メタデータが既に有効になっている場合でも、再起動を tempdb 有効にする必要があります。 詳細については、以下を参照してください:

    警告

    HktempDB をプールにバインドした後、プールは最大設定に達する可能性があり、使用 tempdb するすべてのクエリがメモリ不足エラーで失敗する可能性があります。 例:

    リソース プール 'HkTempDB' のメモリ不足のため、データベース 'tempdb' のページ割り当てを禁止しています。 詳細については、'http://go.microsoft.com/fwlink/?LinkId=510837' を参照してください。 メモリ不足のため XTP がページ割り当てに失敗しました: FAIL_PAGE_ALLOCATION 8

    特定の状況では、メモリ不足エラーが発生した場合、SQL Server サービスが停止する可能性があります。 この問題が発生する可能性を減らすには、メモリ プールを MAX_MEMORY_PERCENT 高い値に設定します。

  5. メモリ最適化 tempdb メタデータ機能は、すべてのワークロードをサポートしているわけではありません。 たとえば、長時間実行される一時テーブルで DDL ステートメントを使用して明示的なトランザクションを使用すると、説明されているシナリオが発生します。 ワークロードにこのようなトランザクションがあり、その期間を制御できない場合は、この機能が環境に適していない可能性があります。 を使用 HkTempDBする前に、広範にテストする必要があります。

詳細

これらのセクションでは、メモリ最適化 tempdb メタデータに関連する一部のメモリ コンポーネントについて詳しく説明します。

ルックアサイド メモリ アロケーター

In-Memory OLTP のルックアサイドは、高速なトランザクション処理を実現するためのスレッド ローカル メモリ アロケーターです。 各スレッド オブジェクトには、ルックアサイド メモリ アロケーターのコレクションが含まれています。 各スレッドに関連付けられている各ルックアサイドには、割り当て可能なメモリ量に関する事前に定義された上限があります。 制限に達すると、スレッドはスピルオーバー共有メモリ プール (VARHEAP) からメモリを割り当てます。 DMV sys.dm_xtp_system_memory_consumers は、ルックアサイドの種類 () と共有メモリ プール (memory_consumer_type_desc = 'LOOKASIDE'memory_consumer_type_desc = 'VARHEAP'memory_consumer_desc = 'Lookaside heap') ごとにデータを集計します。

システム レベルのコンシューマー: tempdb.sys.dm_xtp_system_memory_consumers

約 25 種類のルックアサイド メモリ コンシューマーの種類が上限です。 スレッドがそれらのルックアサイドからより多くのメモリを必要とする場合、メモリは にスピルし、ルックアサイド ヒープに満足します。 使用されるバイトの値が高い場合は、一定の負荷の高い tempdb ワークロードや、一時オブジェクトを使用する実行時間の長いオープン トランザクションの指標になる可能性があります。

-- system memory consumers @ instance  
SELECT memory_consumer_type_desc, memory_consumer_desc, allocated_bytes, used_bytes
FROM sys.dm_xtp_system_memory_consumers 
memory_consumer_type_desc     memory_consumer_desc                   allocated_bytes      used_bytes
------------------------- ------------------------------------------ -------------------- --------------------
VARHEAP                       Lookaside heap                             0                    0
PGPOOL                        256K page pool                             0                    0
PGPOOL                        4K page pool                               0                    0
VARHEAP                       System heap                                458752               448000
LOOKASIDE                     Transaction list element                   0                    0
LOOKASIDE                     Delta tracker cursor                       0                    0
LOOKASIDE                     Transaction delta tracker                  0                    0
LOOKASIDE                     Creation Statement Id Map Entry            0                    0
LOOKASIDE                     Creation Statement Id Map                  0                    0
LOOKASIDE                     Log IO proxy                               0                    0
LOOKASIDE                     Log IO completion                          0                    0
LOOKASIDE                     Sequence object insert row                 0                    0
LOOKASIDE                     Sequence object map entry                  0                    0
LOOKASIDE                     Sequence object values map                 0                    0
LOOKASIDE                     Redo transaction map entry                 0                    0
LOOKASIDE                     Transaction recent rows                    0                    0
LOOKASIDE                     Heap cursor                                0                    0
LOOKASIDE                     Range cursor                               0                    0
LOOKASIDE                     Hash cursor                                0                    0
LOOKASIDE                     Transaction dependent ring buffer          0                    0
LOOKASIDE                     Transaction save-point set entry           0                    0
LOOKASIDE                     Transaction FK validation sets             0                    0
LOOKASIDE                     Transaction partially-inserted rows set    0                    0
LOOKASIDE                     Transaction constraint set                 0                    0
LOOKASIDE                     Transaction save-point set                 0                    0
LOOKASIDE                     Transaction write set                      0                    0
LOOKASIDE                     Transaction scan set                       0                    0
LOOKASIDE                     Transaction read set                       0                    0
LOOKASIDE                     Transaction                                0                    0

データベース レベルのコンシューマー: tempdb.sys.dm_db_xtp_memory_consumers

  • LOB アロケーターは、システム テーブル LOB/行外データに使用されます。

  • テーブル ヒープは、システム テーブルの行に使用されます。

使用されるバイトの値が高い場合は、一定の負荷の高い tempdb ワークロードや、一時オブジェクトを使用する実行時間の長いオープン トランザクションの指標になる可能性があります。