メモリ最適化 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
問題を診断する
問題を診断するためにデータを収集するには、次の手順に従います。
軽量トレースまたは拡張イベント (XEvent) を収集してワークロードを理解
tempdb
し、ワークロードに一時テーブルの DDL ステートメントを使用して実行時間の長い明示的なトランザクションがあるかどうかを確認します。次の 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_ID
Object_ID
XTP_Object_ID
はNULL
です。解決策: 問題の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 メタデータ メモリをチェックに保持するための軽減手順
一時テーブルで DDL ステートメントを使用する実行時間の長いトランザクションを回避または解決するには、一般的なガイダンスとしてトランザクションを短くします。
最大サーバー メモリを増やして、tempdb 負荷の高いワークロードが存在する場合に十分なメモリを動作させることができます。
定期的に実行
sys.sp_xtp_force_gc
します。メモリ不足の可能性からサーバーを保護するには、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
高い値に設定します。メモリ最適化
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
ワークロードや、一時オブジェクトを使用する実行時間の長いオープン トランザクションの指標になる可能性があります。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示