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

診斷問題

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

  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_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 元數據記憶體的風險降低步驟

  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 的查詢都可能會因為記憶體不足錯誤而失敗。 例如:

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

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

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