本文提供解決與記憶體優化 tempdb 元數據功能相關的記憶體不足問題疑難解答。
徵兆
啟用記憶體優化的 tempdb 元數據(HkTempDB)功能後,您可能會看到錯誤 701,指出記憶體不足導致 tempdb 配置問題和 SQL Server 服務崩潰的狀況。 此外,您可能會看到用於記憶體內部 OLTP(Hekaton)的記憶體管理員 MEMORYCLERK_XTP 正在逐漸或快速成長,而且不會縮小。 當 XTP 記憶體沒有上限成長時,您會在 SQL Server 中看到下列錯誤訊息:
不允許資料庫 『tempdb』 的頁面配置,因為資源集區 『default』 中的記憶體不足。 如需詳細資訊,請參閱 '
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
診斷問題
若要收集數據以診斷問題,請遵循下列步驟:
收集輕量型追蹤或擴充事件 (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 的更多記憶體時,記憶體會溢出並由 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 工作負載和/或長時間執行的開放式交易的指標。