記憶體優化的tempdb元資料 (HkTempDB) 記憶體不足錯誤
本文提供解決方法,以針對記憶體優化 tempdb
元數據功能相關的記憶體不足問題進行疑難解答。
徵狀
啟用 HkTempDB) 功能 (記憶體優化tempdb
元數據之後,您可能會看到錯誤 701,指出配置和 SQL Server 服務損毀的記憶體不足例外tempdb
狀況。 此外,您可能會看到 In-Memory OLTP (Hekaton) 的記憶體 MEMORYCLERK_XTP
Clerk 正在逐漸或快速地成長,而且不會縮減。 當 XTP 記憶體成長而沒有上限時,您會在 SQL Server 中看到下列錯誤訊息:
因為資源集區 『default』 中的記憶體不足,所以不允許資料庫 『tempdb』 的頁面配置。 如需詳細資訊,請參閱 '
http://go.microsoft.com/fwlink/?LinkId=510837
'。
當您在 DMVdm_os_memory_clerks上執行查詢時,您會看到配置給記憶體 Clerk 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 來驗證原因,您可能會看到不同的問題案例。 這些案例可以分成下列兩個類別。 若要解決此問題,您可以針對每個案例使用對應的解決方案。 如需如何減輕問題的詳細資訊,請參閱 風險降低步驟,以檢查記憶體優化的tempdb元數據記憶體。
XTP 記憶體耗用量逐漸增加
案例 1
DMV tempdb.sys.dm_xtp_system_memory_consumers 或 tempdb.sys.dm_db_xtp_memory_consumers 會顯示配置的位元組與已使用位元組之間的差異很大。
解決方法:若要解決此問題,您可以在 SQL Server 2019 CU13、SQL Server 2022 CU1 或更新版本中執行下列命令,
sys.sp_xtp_force_gc
以釋出已配置但未使用的位元組。注意事項
從 SQL Server 2022 CU1 開始,您只需要執行預存程式一次。
/* 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) 設定器或數據表堆積,其中Object_ID
、XTP_Object_ID
Index_ID
和 為NULL
的大型物件中顯示設定和使用位元組的高值 (。解決方式:針對問題14535149套用 2019 #DE187A36359144CDDB9F617778693D019 CU16。
案例 4
持續成長的「VARHEAP\記憶體內部堆積」XTP 資料庫記憶體取用者會導致記憶體不足錯誤 41805。
解決方式:SQL Server17 CU25 和更新版本中14087445已識別並解決此問題,目前正在檢查是否要移植到 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 語句明確開啟的交易,將不允許使用元數據釋放數據表堆積和 lookaside 堆積,以供後續交易使用
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
數據。
Lookaside 記憶體配置器
In-Memory OLTP 中的 Lookaside 是線程本機記憶體配置器,可協助達成快速交易處理。 每個線程物件都包含 lookaside 記憶體配置器的集合。 與每個線程相關聯的每個外觀都有預先定義的上限,其可配置的記憶體數量。 達到限制時,線程會從溢出的共用記憶體集區配置記憶體 (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個外觀記憶體取用者類型是上限。 當線程需要來自這些外觀的更多記憶體時,記憶體會溢出至 ,並滿足 lookaside 堆積。 使用位元組的高值可能是使用暫存物件的常數繁重 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 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應