次の方法で共有


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

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

現象

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

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

DMV dm_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 メタデータ メモリをチェック状態に保つためのMitigation 手順を参照してください。

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

  • シナリオ 1

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

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

    Note

    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 は、メモリ コンシューマーの種類の VARHEAPLOOKASIDEに割り当て済みバイトと使用済みバイト数の高い値を示します。

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

    Note

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

  • シナリオ 3

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

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

  • シナリオ 4

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

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

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

  • シナリオ 5

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

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

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

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

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

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

  2. max サーバー メモリを増やして、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 メタデータに関連するいくつかのメモリ コンポーネントについて詳しく説明します。

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

インメモリ 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 、または一時オブジェクトを使用する実行時間の長いオープン トランザクションのインジケーターになる可能性があります。