記憶體優化tempdb元資料 (HkTempDB) 記憶體不足錯誤
本文提供解決與記憶體優化 tempdb
元數據功能相關的記憶體不足問題疑難解答。
徵兆
啟用記憶體優化 tempdb
元數據 (HkTempDB) 功能之後,您可能會看到錯誤 701 ,指出配置和 SQL Server 服務當機的記憶體不足例外 tempdb
狀況。 此外,您可能會看到記憶體內部 OLTP (Hekaton) 的記憶體 Clerk MEMORYCLERK_XTP
正在逐漸或快速成長,而且不會縮小。 當 XTP 記憶體沒有上限成長時,您會在 SQL Server 中看到下列錯誤訊息:
不允許資料庫 『tempdb』 的頁面配置,因為資源集區 『default』 中的記憶體不足。 如需詳細資訊,請參閱 '
http://go.microsoft.com/fwlink/?LinkId=510837
'。
當您在 DMV dm_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
。解決方案:針對問題套用 SQL Server 2019 CU16 14535149。
案例 4
持續成長的「VARHEAP\Storage 內部堆積」XTP 資料庫記憶體取用者會導致記憶體不足錯誤 41805。
解決方案:SQL Server 17 CU25 和更新版本中已識別並解決的問題14087445正在檢查中,以移植到 SQL Server 2019。
XTP 記憶體耗用量突然暴增或快速增加
案例 5
DMV
tempdb.sys.dm_db_xtp_memory_consumers
會顯示資料表堆積中已設定或已使用位元組的高值,但Object_ID
不是NULL
。 此問題最常見的原因是在臨時表上以 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
的任何查詢可能會因為記憶體不足錯誤而失敗。 例如:不允許資料庫 『tempdb』 的頁面配置,因為資源集區 『HkTempDB』 中的記憶體不足。 如需詳細資訊,請參閱 '
http://go.microsoft.com/fwlink/?LinkId=510837
'。 由於記憶體壓力,XTP 頁面配置失敗:FAIL_PAGE_ALLOCATION 8在某些情況下,如果發生記憶體不足錯誤,SQL Server 服務可能會停止。 若要降低發生這種情況的機會,請將記憶體集區的
MAX_MEMORY_PERCENT
設定為高值。記憶體優化的
tempdb
元數據功能不支援每個工作負載。 例如,在長時間執行的臨時表上使用具有 DDL 語句的明確交易會導致所述的案例。 如果您的工作負載中有這類交易,且無法控制其持續時間,則此功能可能不適合您的環境。 您應該在使用 之前HkTempDB
廣泛測試。
其他相關資訊
這些區段提供有關記憶體優化 tempdb
元數據中某些記憶體元件的詳細數據。
Lookaside 記憶體配置器
記憶體內部 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/Off-row資料。
數據表堆積用於系統數據表數據列。
已使用位元組的高值可能是使用暫存物件的常數繁重 tempdb
工作負載和/或長時間執行的開放式交易的指標。