Sql-Server

SQL Server 實例如何恢復使用的記憶體

  • March 23, 2021

我知道這個問題可能已經回答了很多次,但我需要一個更好的方法來解決它,或者向我的老闆證明這是一種正常的行為,或者我忽略了一些事情。

我不是 DBA,我是開發人員,就像我以前的工作一樣,我必須接受 DBA Mantle,因為我們現場沒有正式的 DBA,或者沒有人願意認真對待這件事。

我有三個 SQL Server 實例,一個使用 SQL 2008 R2,兩個使用 SQL 2016。全部來自生產環境。

SQL 2008 R2 來自我們的主系統,它託管在 Hyper-V 中的虛擬伺服器中,並且是專用數據庫伺服器。該伺服器上沒有分配其他應用程序,它是一個純數據庫伺服器。

問題是伺服器配置了 30 GB 的 RAM,而 SQL Server 配置為使用最小 4 GB 到最大 22 GB 的記憶體。

}記憶體參數配置

如果我重新啟動,顯然伺服器記憶體使用量在伺服器性能管理器中變為一條直線,將記憶體從已使用的記憶體中釋放到配置的最小值。

重啟後的記憶體

我需要幫助理解這種情況,因為所有文件都指向一個無可辯駁的事實,即這在 SQL Server 中是正常的,我已經記錄了自己,但我的老闆和同事表示這對數據庫來說不是正常行為。如果我做數字,我認為伺服器正在請求更多記憶體。他們說這不是 SQL Server 的正常行為,並且我們忽略了一些東西(賈伯斯和其他東西)。為了監控或嘗試確定伺服器行為,我開始每兩個小時發送一次數據庫健康報告,以嘗試檢查發生了什麼。對於他們來說,預期的行為是 SQL Server RAM 應該在性能圖表中上升和下降,而不是一直保持在頂部,據我了解,這是預期的行為或 SQL Server 的設計。

數據庫健康報告

但是在不同的時間點,作業上升到執行,並且它們正常完成,一些長時間執行的事務正在執行,但是當我在生成報告後對它們執行查詢時,它們就消失了。

有什麼我忽略的嗎?這是正常的嗎?有沒有辦法在不重啟實例的情況下釋放記憶體?我已經嘗試了一堆解決方案

這是正常的嗎?

是的。

我的老闆和同事說這不是數據庫的正常行為

SQL Server 會將其記憶體使用量增加到您的配置max server memory,並且僅當系統的物理記憶體不足時才會減少其記憶體使用量。

如果系統有足夠的可用 RAM,SQL Server 將使用它來記憶體數據和執行計劃,並有可用的記憶體來執行查詢。

如果 Windows 發出全域“記憶體不足”信號,SQL Server 會通過修剪其記憶體和取消分配記憶體來做出響應。

這在文件中有詳細說明:

SQL Server 數據庫引擎的預設記憶體管理行為是根據需要獲取盡可能多的記憶體,而不會在系統上造成記憶體短缺。SQL Server 數據庫引擎通過使用 Microsoft Windows 中的記憶體通知 API 來執行此操作。

當 SQL Server 動態使用記憶體時,它會定期查詢系統以確定可用記憶體量。維護此可用記憶體可防止作業系統 (OS) 分頁。如果可用記憶體較少,SQL Server 會向作業系統釋放記憶體。如果有更多可用記憶體,SQL Server 可能會分配更多記憶體。SQL Server 僅在其工作負載需要更多記憶體時才添加記憶體;靜止的伺服器不會增加其虛擬地址空間的大小。

Max server memory 控制 SQL Server 記憶體分配、編譯記憶體、所有記憶體(包括緩衝池)、查詢執行記憶體授予、鎖管理器記憶體和 CLR1 記憶體(基本上是在 sys.dm_os_memory_clerks 中找到的任何記憶體職員)。

記憶體管理架構指南 - 動態記憶體管理

有沒有辦法在不重啟實例的情況下釋放記憶體?

您可以減少最大伺服器記憶體,SQL Server 將修剪其記憶體並線上減少其記憶體使用量。在它下降後,您可以max server memory再次增加,SQL Server 將隨著時間的推移重新增長記憶體。

但是這個程序在操作上是沒有意義的。其他任何東西都不需要記憶體,如果需要,SQL Server 將通過降低記憶體使用率來響應系統記憶體不足信號。

大衛布朗的答案是你能找到的最權威的答案。你現在可以回到你的同事那裡說“嘿,我和微軟的某個人交談過,答案是這對於 SQL Server 來說是完全正常的行為,按照設計。我認為我們中沒有人比創建 /自己維護產品。 ”(如果你在和你的老闆交談,可能會忽略最後一部分。:) 如果 Microsoft 員工的口碑不夠好,你可以向他們展示它在產品中是正確的監控記憶體使用情況 - 配置 SQL Server 最大記憶體中的文件:

預設情況下,SQL Server 實例可能會隨著時間的推移消耗伺服器中大部分可用的 Windows 作業系統記憶體。記憶體一旦被獲取,除非檢測到記憶體壓力,否則不會被釋放。這是設計使然,並不表示 SQL Server 程序中存在記憶體洩漏。

但是我想補充幾件重要的事情:您的同事這麼認為的原因是因為他們在一個正常的伺服器環境中是正確的,這意味著他們可以處理多個應用程序,其中共享很重要,而且資源高峰時間過長可能是一個問題或者是應用程序存在嚴重記憶體洩漏問題的跡象,例如。

在伺服器環境中,該伺服器旨在為僅一個應用程序(在這種情況下為SQL Server )盡可能最佳地執行,那麼只有允許該應用程序盡可能多的可用資源才有意義(在合理範圍內,作業系統需要一點點資源本身),以便應用程序(SQL Server)可以盡可能高效地執行。

正如大衛在他的回答中提到的,特別是在記憶體方面,SQL Server記憶體了很多東西。但是它記憶體的最重要的東西之一是表數據的數據頁面,這樣當執行重複查詢需要訪問這些頁面中的任何數據時,它可以直接從記憶體而不是性能較低的磁碟中獲取它. 想像一下,如果每次執行查詢時需要從磁碟獲取所有數據,尤其是在討論數百萬行/千兆字節的數據時。這對任何人來說都不是一個有趣的時間。

SQL Server也以其他方式表現出這種行為,例如當數據庫文件(事務日誌和數據文件)增長時,它們如何保留一定數量的額外磁碟空間(基於配置的數據庫選項)。雖然SQL Server實際上並未主動使用額外的磁碟空間,但這樣做可以使其在需要時更有效地執行(內部數據以較慢的速度增長),而不是不斷地從磁碟請求空間,這將是次要的表現。它還保證SQL Server在增長時將擁有所需的空間。

最後,我要說的最後一點是,重新啟動伺服器或SQL Server 實例實際上會適得其反。通過清除記憶體中的所有記憶體對象,您的SQL Server可能會在第一天左右在重建記憶體時執行較慢,並且您可能會看到更多的性能問題,而不是離開它並讓SQL Server完成它的設計目標。


長話短說,在一個唯一目的是支持一個應用程序(本例中為SQL Server)的環境中,將大部分資源分配給該應用程序是正常的,這樣它才能盡可能高效地執行。否則,如果資源被閒置而不被使用,它們就是一種浪費(物理上和金錢上)。

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