SQL Server RAM 使用情況 - 如何找出它的去向?
簡潔版本
SQL Server 正在使用 34 GB 的 RAM。但是當查詢Memory Consumption Report、緩衝池大小和 ad-hoc 查詢大小時,它加起來只有 2 GB 左右。其他 32 GB 的 RAM 在做什麼?
先發製人:“您應該限制 SQL Server 可以使用的 RAM 量。” 可以說它的上限為
x
. 這只是將我的問題變成了“其他x
GB 的 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 程序,它應該很快釋放記憶體。