SQL Server 記憶體優化 tempdb 元數據記憶體使用量持續增長
問題
我們啟用了 sp_configure ’tempdb metadata memory-optimized’ = 1,現在 tempdb 元數據在我們的一台伺服器上佔用了 400 GB 以上,並且還在繼續增長。記憶體使用量有所下降,但通常它會不斷增長它的記憶體使用量。我們已經有幾次伺服器實際上崩潰了,因為沒有足夠的記憶體供其他系統程序修改 tempdb 並導致整個伺服器停機。
我要問的問題
如何防止 SQL Server 記憶體中優化的 tempdb 元數據持續增長並使我的伺服器崩潰?如果有的話,我可以查看哪些其他資訊來找出消耗這麼多記憶體的原因?
有關問題的數據
sys.dm_os_memory_clerks
以下查詢目前返回 438 GB。
SELECT SUM(domc.pages_kb / 1024.0 / 1024.0) AS pages_gb FROM sys.dm_os_memory_clerks AS domc WHERE domc.type LIKE 'MEMORYCLERK_XTP'
sys.dm_db_xtp_memory_consumers
以下查詢提供了記憶體使用量最大 (290 GB) 為 memory_consumer_id of 113 - ‘LOB Page Allocator’ 的數據。它沒有object_id 或xtp_object_id,所以我猜它是一個數據庫範圍的對象。
SELECT ddxmc.memory_consumer_id , ddxmc.memory_consumer_type_desc , ddxmc.memory_consumer_desc , ddxmc.object_id , ddxmc.xtp_object_id , ddxmc.used_bytes / 1024.0 / 1024.0 / 1024.0 AS used_gb FROM sys.dm_db_xtp_memory_consumers AS ddxmc ORDER BY ddxmc.allocated_bytes DESC
環境
版本:SQL Server 2019 CU9 -
機箱上的企業記憶體:3 TB
實例類型:故障轉移集群實例
作業系統:Windows Server 2019 標準
CPU 核心數:80 個物理核心(我們最近不得不增加這個數字) Tempdb 的數量文件:64 複製:此伺服器是事務複製的發布者和訂閱者。
使用模式
我們是 tempdb 的重度使用者。我們一直在儲存過程中不斷地創建和刪除臨時表和表變數。我們需要處理大量數據,傳入數據列表,然後將這些數據列表轉換為表格來處理結果集數據,而不是一次處理一條資訊。由於 tempdb 的大量流失,我們不得不實現記憶體中優化的 tempdb 以減輕我們遇到的 PAGELATCH_* 等待。
我很確定沒有任何記憶體優化的使用者表。當我執行以下查詢時,我只看到
SYSTEM_TABLE
類型對象:SELECT * FROM sys.dm_db_xtp_index_stats AS ddxis JOIN sys.objects AS o ON o.object_id = ddxis.object_id
我知道的事情和我嘗試過的事情
記憶體垃圾收集只能清理比最舊事務更早的項目。
我很清楚垃圾收集只能發生在比最舊事務更早的行上,因此我已經停止了所有長時間執行的 SQL 代理作業和任何其他超過 5 分鐘的程序。不幸的是,我們的記憶體使用量並沒有回落。我們確實有舊會話,但根據以下查詢,它們都沒有打開任何事務。
SELECT * FROM sys.dm_exec_sessions AS des WHERE des.open_transaction_count > 0
複製
為了排除複製,我確實暫時停止了此伺服器的發布和訂閱代理。記憶體使用沒有變化。
檢查點
我在 tempdb 中執行了“CHECKPOINT”。記憶體使用量沒有下降。
DBCC FREEPROCCACHE - 擺脫舊的臨時表
為了刪除正在記憶體的舊臨時表,我清除了查詢計劃記憶體,並通過執行以下查詢驗證了臨時表是否已重新創建。這並沒有導致記憶體使用量大幅下降。
SELECT * FROM sys.tables AS t WHERE t.name LIKE '#%' AND t.create_date < 'TimeOfClearingPlanCache'
其他可能的解決方案
重新啟動 SQL Server
我們可以重新啟動 SQL Server,它確實可以緩解一段時間的問題,但一段時間後記憶體使用量確實會再次增加。雖然這是一種解決方法,但這是一個我們不太喜歡的糟糕解決方案。
關閉“記憶體中優化的 Tempdb”
我們可以關閉“記憶體中優化的 tempdb”,但是我們會受到我們之前經歷過的大量 PAGELATCH_* 等待的影響。我們有 64 個 tempdb 文件來幫助減少我們看到的爭用,但在我們繁忙的時期,即使這樣也不夠。這可能是一種選擇,但最好是我們能找到記憶體使用量持續增長的原因。
微軟的Pam Lahoud SQL Enterprise Team 首席項目經理在推特上說:
並在這里通過評論貢獻:
有一些已知問題可能會在這裡發揮作用。如果可以的話,最好打開一個有支持的案例,我們在這些問題上擁有的數據越多,我們就越有可能找到解決辦法。
根據Klaus Ondrich的說法,此問題已在 SQL Server 2019 的累積更新 13 中修復。
此問題已在SQL Server 2019 CU13中修復(由我們的升級工程師確認)。
此外,還有一個稱為
sys.sp_xtp_force_gc 'databasename'
強制垃圾收集的新過程。不幸的是,CU 文章沒有提及或描述這個新程序。