Sql-Server

SQL Server 記憶體優化 tempdb 元數據記憶體使用量持續增長

  • October 14, 2021

問題

我們啟用了 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 文章沒有提及或描述這個新程序。

引用自:https://dba.stackexchange.com/questions/292370