共用方式為


內存最佳化tempdb元資料(HkTempDB)內存不足錯誤

本文提供解決與記憶體優化 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

診斷問題

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

  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 的更多記憶體時,記憶體會溢出並由 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 工作負載和/或長時間執行的開放式交易的指標。