記憶體優化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

診斷問題

若要收集數據以診斷問題,請遵循下列步驟:

  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 來驗證原因,您可能會看到問題的不同案例。 這些案例可以分成下列兩個類別。 若要解決此問題,您可以針對每個案例使用對應的解決方案。 如需如何減輕問題的詳細資訊,請參閱 緩和步驟以保持記憶體優化的 tempdb 元數據記憶體檢查

XTP 記憶體耗用量逐漸增加

  • 實例 1

    DMV tempdb.sys.dm_xtp_system_memory_consumerstempdb.sys.dm_db_xtp_memory_consumers 會顯示配置位元組與已使用位元節之間的較大差異。

    解決方案:若要解決此問題,您可以在 SQL Server 2019 CU13SQL 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 會顯示記憶體取用者型別 VARHEAPLOOKASIDE的已配置和已使用位元組的高值。

    解決方案:檢查暫存數據表上涉及 DDL 語句的長時間執行明確交易,並藉由保持交易簡短的方式從應用程式端解析。

    注意

    若要在測試環境中重現此問題,您可以在臨時表上使用數據定義語言 (DDL) 語句來建立明確的 交易 ,並在其他活動發生時長時間保持開啟狀態。

  • 案例 3

    DMV tempdb.sys.dm_db_xtp_memory_consumers 會顯示大型物件 (LOB) 配置器或資料表堆積中已配置及使用位元組的高值,其中 Object_IDXTP_Object_IDIndex_IDNULL

    解決方案:針對問題套用 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 元數據記憶體的風險降低步驟

  1. 若要避免或解決在臨時表上使用 DDL 語句的長時間執行交易,一般指引是讓交易保持簡短。

  2. 增加 最大伺服器記憶體 ,以允許足夠的記憶體在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 的任何查詢可能會因為記憶體不足錯誤而失敗。 例如:

    不允許資料庫 『tempdb』 的頁面配置,因為資源集區 『HkTempDB』 中的記憶體不足。 如需詳細資訊,請參閱 'http://go.microsoft.com/fwlink/?LinkId=510837'。 由於記憶體壓力,XTP 頁面配置失敗:FAIL_PAGE_ALLOCATION 8

    在某些情況下,如果發生記憶體不足錯誤,SQL Server 服務可能會停止。 若要降低發生這種情況的機會,請將記憶體集區的 MAX_MEMORY_PERCENT 設定為高值。

  5. 記憶體優化的 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 工作負載和/或長時間執行的開放式交易的指標。