Sql-Server

SQL Server RAM 使用情況 - 如何找出它的去向?

  • January 9, 2022

簡潔版本

SQL Server 正在使用 34 GB 的 RAM。但是當查詢Memory Consumption Report、緩衝池大小和 ad-hoc 查詢大小時,它加起來只有 2 GB 左右。其他 32 GB 的 RAM 在做什麼?

先發製人:“您應該限制 SQL Server 可以使用的 RAM 量。” 可以說它上限為x. 這只是將我的問題變成了“其他xGB 的 RAM 在做什麼?”

長版

我有一個消耗 32 GB RAM 的 SQL Server 實例:

在此處輸入圖像描述

那不是 32 GB 的虛擬記憶體;它實際上消耗了 32 GB 的物理記憶體(在 RAM 晶片上)——稱為*“工作集”*。

它不像是與其他程序共享的。基本上所有這些都是 SQL Sever 私有的:

在此處輸入圖像描述

  • 私有工作集:33,896,700 字節

所有這些 RAM 都在做什麼?!

數據庫的緩衝池記憶體使用情況

因此,我們按數據庫查詢記憶體使用情況——因為緩衝池記憶體了數據庫中的頁面:

--Memory usage server wide
;WITH src AS
(
   SELECT
       database_id,
       COUNT_BIG(*) AS db_buffer_pages
   FROM sys.dm_os_buffer_descriptors
   --WHERE database_id BETWEEN 5 AND 32766
   GROUP BY database_id
)
SELECT
   CASE [database_id] WHEN 32767 THEN 'Resource DB' ELSE DB_NAME([database_id]) END AS [Database Name],
   db_buffer_pages AS BufferPages,
   db_buffer_pages /128.0 AS BufferMB
FROM src
ORDER BY db_buffer_pages DESC
OPTION(RECOMPILE, MAXDOP 1);

總共4.5 MB的 32 GB。

TempDB 使用最多(1.4 MB),其餘的從那裡開始:

在此處輸入圖像描述

5 MB 的 32 GB - 佔不了多少

是的,這可能看起來很低——但這很可能是因為我DBCC DROPCLEANBUFFERS先打電話。

查詢計劃記憶體

接下來我們查詢查詢計劃記憶體。所有這些 T-SQL 語句都必須編譯成一個巨大的計劃,並且這些計劃記憶體在 RAM 中。

--Server-wide memory usage of plan cache
SELECT
   [cacheobjtype], ObjType,
   COUNT(1) AS Plans,
   SUM(UseCounts) AS UseCounts,
   SUM(CAST(size_in_bytes AS real)) / 1024.0 / 1024 AS [SizeMB]
FROM sys.dm_exec_cached_plans
--where [cacheobjtype] = 'Compiled Plan' and [objtype] in ('Adhoc', 'Prepared')
GROUP BY CacheObjType, ObjType
ORDER BY SizeMB DESC
OPTION(RECOMPILE, MAXDOP 1)

現在我們可以看到有多少記憶體用於儲存各種查詢計劃:

總共250 KB -低於失去的 32 GB。

**注意:**是的,這可能看起來很低——但這很可能是因為我先呼叫DBCC FREEPROCCACHE

記憶體消耗報告

上面的查詢向我顯示了以下使用者使用的 RAM:

  • 緩衝池(從磁碟記憶體到記憶體數據庫頁面)
  • 查詢計劃記憶體

這就是全部。但 SQL Server 確實提供了記憶體消耗報告

此報告提供有關實例內組件的記憶體消耗的詳細數據

旁白“沒有”

該報告有點難以閱讀:

在此處輸入圖像描述

但最終的細分是:

  • MEMORYCLERK_SOSNODE:131,832 KB
  • MEMORYCLERK_SOSMEMMANAGER:71,464 KB
  • USERSTORE_DBMETADATA:67,432 KB
  • USERSTORE_SCHEMAMGR:55,784 KB
  • MEMORYCLERK_SQLSTORENG:54,280 KB
  • MEMORYCLERK_SQLBUFFERPOOL:30,576 KB
  • 其他:145,056 KB

總計:556,424 KB → 544 MB

即使我們將其四捨五入到 1 GB:它仍然與 32 GB 相去甚遠。

那麼記憶體去哪了?

是的,我可以將 SQL Server 的記憶體限制為 25 GB。但這只會將我的問題改為:

SQL Server 使用 25 GB RAM 的目的是什麼;記憶去哪兒了?

因為這聽起來很像我的記憶體洩漏

  • 伺服器:SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64)

伺服器正常執行時間

可以查詢伺服器正常執行時間(創建 tempdb):

--Use creation date of tempdb as server start time

SELECT SERVERPROPERTY(‘SERVERNAME’) AS ServerName, create_date AS ServerStartedDate FROM sys.databases WHERE NAME=‘tempdb’;

  • 伺服器開始日期2021-12-21 15:46:26.730

CLR 程序集

SELECT * FROM sys.assemblies

連結伺服器

select provider, provider_string from sys.servers

如果您DBCC DROPCLEANBUFFERS在檢查記憶體使用情況之前執行,它只會顯示 SQL Server 正在使用的少量記憶體,但執行此命令不會將釋放的記憶體釋放回作業系統。

DBCC DROPCLEANBUFFERS將從緩衝池中刪除所有乾淨的緩衝區,但是,sqlservr.exe 將保留之前分配的記憶體,並在DBCC DROPCLEANBUFFERS執行後立即重新使用此記憶體來重新開始在緩衝池中分配頁面。如果您在伺服器上遇到記憶體不足的情況,則 sqlservr.exe可能會開始將記憶體釋放回作業系統,除非您啟用了Lock Pages in Memory 。

這些記憶體消耗查詢/報告不會立即報告任何感興趣的內容,DBCC DROPCLEANBUFFERS因為為程序分配的記憶體現在基本上未使用。要查看 SQL Server 如何使用其記憶體分配,請在執行之前執行這些查詢/報告DBCC DROPCLEANBUFFERS(實際上根本不應該在生產伺服器上執行)。

注意:您可以強制 SQL Server 將記憶體釋放回作業系統,方法是在DBCC DROPCLEANBUFFERS. 這通常不是即時的,但大多數未使用的頁面分配給 sqlservr.exe 程序,它應該很快釋放記憶體。

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