SQL SERVER 內存學習系列(二)-DMV查看內存信息


    內存管理在SQL Server中有一個三級結構。底部是內存節點,這是最低級的分配器,用於SQL Server的內存。第二個層次是由內存Clerk組成,這是用來訪問內存節點和緩存存儲,緩存存儲則用於緩存。最上層包含內存對象,它提供了一個比內存Clerk更小程度的粒度,內存對象允許直接。只有Clerk可以訪問存儲節點,來分配內存,所以每一個需要分配大量內存的組件都需要在SQL Server服務啟動時創建它自己的內存Clerk。

以前版本的SQL Server需要SQL Server內存分配之外的VAS空間,以滿足多頁分配(MPA)和CLR內存要求。MPA用於每當一個組件需要一個單一分配大於8KB的時候,單頁分配器處理任何不大於8KB的時候。在SQL Server 2012中,只有一個頁面分配器用於所有的請求,他們都直接來自於SQL Server的內存分配。在SQL Server 2012中,CLR分配也是直接來自於SQL Server的內存分配,這使得它更容易規模化SQL Server的內存需求

    2008R2

    

    2012

    

 

    從上面的圖可以看出,SQL Server 2012 多了一個memory Manager,它來統一響應SQL Server 內部各種組件內存申請的請求。因為這個原因,在SQL Server 2012里面,max server memory 不再像以前的版本那樣,只控制buffer pool的大小,也包括那些大於8kb 的內存請求。也就是, max server memory 能夠更准確地控制SQL Server 的內存使用了(並非完全控制)

    

    SQL SERVER使用Memory Clerk的方式統一管理內存的分配和回收,所以這使得我們使用SQL SERVER內存變得容易,因為需要我們設置的東西很少。除了限制一下max server memory 我貌似也想不到什么需要干涉SQL 使用內存的了(當然類似resource governor這種東西除外哈)。

    SQL SERVER可以知道每個Clerk使用了多少內存從而也知道自己總共使用了多少內存,這些信息都在DMV視圖中可以查詢的到,雖然大部分管理中都是使用性能監控器但是DMV的信息也是一種比較好的監控手段。另外很多人喜歡用DBCC 語句查看SQL各種信息,我也不例外,但是現在的DMV在產品技術不斷發展也越來越全面細致了。

---------------轉載請注明出處------------http://www.cnblogs.com/double-K/p/5063024.html--------------------

    1.memory clerk :跟蹤內存sys.dm_os_memory_clerks 這個視圖在05,08,12中都有變化

    

-----查看內存節點直接映射到NUMA節點
select * from sys.dm_os_memory_nodes


----
----查看memory clerk信息
----2012 中 pages_kb = 2008 中 single_pages_kb + multi_pages_kb
----2005 請自行查找
SELECT [type],
memory_node_id,
pages_kb,
virtual_memory_reserved_kb,  
virtual_memory_committed_kb,
shared_memory_reserved_kb,
shared_memory_committed_kb,
awe_allocated_kb  
FROM sys.dm_os_memory_clerks  
ORDER BY [type] DESC;  

-----不區分memory_node_id 查看總體clerk分配情況
SELECT [type],
sum(pages_kb) as [pages_kb],
sum(virtual_memory_reserved_kb) as [vm reserved],  
sum(virtual_memory_committed_kb) as [vm committed],
sum(shared_memory_reserved_kb) as [sm reserved],
sum(shared_memory_committed_kb) as [sm committed],
sum(awe_allocated_kb) as [awe allocated]  
FROM sys.dm_os_memory_clerks  
group by [type]
ORDER BY [type] DESC;  

      白皮書的字段說明:

      

列名                                       

數據類型                                       

說明                                       

memory_clerk_address                                                              

varbinary(8)                                       

指定內存分配器的唯一內存地址。                     這是主鍵列。 不可為 Null。

類型                                                              

nvarchar(60)                                       

指定內存分配器的類型。                     每個分配器都具有特定類型,例如,CLR Clerks MEMORYCLERK_SQLCLR。 不可為 Null。

name                                                              

nvarchar(256)                                       

指定在內部為此內存分配器分配的名稱。                     一個組件可擁有多個特定類型的內存分配器。 組件可選擇使用特定名稱來標識相同類型的內存分配器。 不可為 Null。

memory_node_id                                                              

smallint                                       

指定內存節點的 ID。                     不可為 Null。

single_pages_kb                                                              

bigint                                       

 

 

適用於:SQL Server 2008 到 SQL Server 2008 R2。                                                       

pages_kb                                                              

bigint                                       

指定為此內存分配器分配的頁內存量 (KB)。                     不可為 Null。

 

適用於:SQL Server 2012 到 SQL Server 2014。                                                       

multi_pages_kb                                                              

bigint                                       

分配的多頁內存量 (KB)。                     這是使用內存節點的多頁分配器分配的內存量。 此內存在緩沖池外面分配,利用了內存節點虛擬分配器的優勢。 不可為 Null。

 

適用於:SQL Server 2008 到 SQL Server 2008 R2。                                                       

virtual_memory_reserved_kb                                                              

bigint                                       

指定內存分配器保留的虛擬內存量。                     不可為 Null。

virtual_memory_committed_kb                                                              

bigint                                       

指定內存分配器提交的虛擬內存量。                     提交的內存量應始終小於保留的內存量。 不可為 Null。

awe_allocated_kb                                                              

bigint                                       

指定在物理內存中鎖定且未由操作系統調出的內存量 (KB) 。                     不可為 Null。

shared_memory_reserved_kb                                                              

bigint                                       

指定內存分配器保留的共享內存量。                     保留以供共享內存和文件映射使用的內存量。 不可為 Null。

shared_memory_committed_kb                                                              

bigint                                       

指定內存分配器提交的共享內存量。                     不可為 Null。

page_size_in_bytes                                                              

bigint                                       

指定此內存分配器的頁分配粒度。                     不可為 Null。

page_allocator_address                                                              

varbinary(8)                                       

指定頁分配器的地址。                     此地址對於內存分配器唯一,且可在 sys.dm_os_memory_objects 中使用,以查找綁定到此分配器的內存對象。 不可為 Null。

host_address                                                              

varbinary(8)                                       

指定用於此內存分配器的主機的內存地址。                     有關詳細信息,請參閱 sys.dm_os_hosts (Transact-SQL) Microsoft SQL Server Native Client 等組件通過宿主接口訪問 SQL Server 內存資源。

0x00000000 = 屬於 SQL Server 的內存分配器。                                       

不可為 Null。

     2.緩存

    SQL Server使用三種類型的緩存機制:對象存儲,緩存存儲和用戶存儲。對象存儲用於緩存同種類型的無狀態的數據,但緩存存儲和用戶存儲是最常見的。兩者很相似,因為都是緩存。它們的主要區別是,用戶存儲必須是由使用開發框架的自身存儲語義來創建,而緩存存儲則實現對前面提到的用於提供更小內存分配粒度的存儲對象的支持。從本質上講,用戶存儲主要用於微軟內部不同的開發團隊實現SQL Server功能的特定緩存,所以你可以以相同的方式看待緩存存儲和用戶存儲。要查看SQL Server上實施的不同的緩存,可以使用DMV sys.dm_os_memory_cache_counters。例如,運行下面的查詢會顯示所有可用的緩存,它們以空間消費的總量排序:

    

SELECT [name],[type],pages_kb,entries_count  
FROM sys.dm_os_memory_cache_counters  
ORDER BY pages_kb DESC;  

    

    3.緩沖池

    緩沖池包含並管理SQL Server的數據緩存。其內容信息可通過DMV sys.dm_os_buffer_descriptors DMV來查看。例如,下面的查詢將返回每個數據庫的緩存使用量,以MB為單位:

    

SELECT count(*)*8/1024 AS 'Cached Size (MB)'  
,CASE database_id WHEN 32767 THEN 'ResourceDb'  
ELSE db_name(database_id) END AS 'Database'  
FROM sys.dm_os_buffer_descriptors  
GROUP BY db_name(database_id),database_id  
ORDER BY 'Cached Size (MB)' DESC  

    

    4.計划緩存

    創建執行計划是好事且資源密集的,因此,如果SQL Server能找到執行一段代碼的好方式,將是一件有意義的事,應該嘗試為后續的請求復用它。計划緩存用於緩存所有的執行計划,以備復用。你可以使用DMV sys.dm_exec_cached_plans來查看計划緩存中的內容和確定它當前的大小:

    

    

SELECT count(*) AS 'Number of Plans',  
sum(cast(size_in_bytes AS BIGINT))/1024/1024 AS 'Plan Cache Size (MB)'  
FROM sys.dm_exec_cached_plans  

    下面是一些其他的網絡常用腳本:

--查看數據緩沖區里面的臟數據頁
SELECT  OBJECT_NAME(p.[object_id]) AS [TableName] 
, ISNULL(i.name, '-- HEAP --') AS ObjectName 
, COUNT(1) AS PagesCount
FROM sys.allocation_units AS a 
INNER JOIN sys.dm_os_buffer_descriptors AS b 
ON a.allocation_unit_id = b.allocation_unit_id 
INNER JOIN sys.partitions AS p 
INNER JOIN sys.indexes i 
ON p.index_id = i.index_id 
AND p.[object_id] = i.[object_id] 
ON a.container_id = p.hobt_id 
WHERE b.database_id = DB_ID() 
AND B.is_modified=1
GROUP BY p.[object_id], i.name 

--對象的分布
SELECT  TOP 50 OBJECT_NAME(p.[object_id]) AS [TableName] 
, ISNULL(i.name, '-- HEAP --') AS ObjectName 
, COUNT(1) * 8 / 1024 AS PagesCount_mb
FROM sys.allocation_units AS a 
INNER JOIN sys.dm_os_buffer_descriptors AS b 
ON a.allocation_unit_id = b.allocation_unit_id 
INNER JOIN sys.partitions AS p 
INNER JOIN sys.indexes i 
ON p.index_id = i.index_id 
AND p.[object_id] = i.[object_id] 
ON a.container_id = p.hobt_id 
WHERE b.database_id = DB_ID() 
--AND B.is_modified=1
GROUP BY p.[object_id], i.name 
ORDER By PagesCount_mb DESC


----緩沖池內數據庫緩沖池中各個數據庫的分布情況---
select case database_id when 32767 then 'resourcedb' else DB_NAME(database_id) end as database_name,
COUNT(*) as cached_pages_count
from sys.dm_os_buffer_descriptors
group by db_name(database_id),database_id
order by cached_pages_count desc

---------緩沖池中前十位消耗內存最大的內存組件-----
select top(100)  type ,SUM(pages_kb) as [spa mem,kb]
--select * 
from sys.dm_os_memory_clerks
group by type
order by SUM(pages_kb) desc

 

---------------轉載請注明出處------------http://www.cnblogs.com/double-K/p/5063024.html--------------------

    總結:內存相關的DMV視圖有很多用法也很靈活,對排查內存問題很有幫助,但話說回來,既然SQL SERVER 選擇自己管理分配內存,這也讓用戶可干預的很少,所以個人經驗:目前內存出現問題,只能出內存的使用者角度出發,分析為什么會占用這么多內存,是否可以減少內存的使用?總之我們能夠干預的內存使用還是很有限的,這個似乎有些坑了。有更好的辦法也還請賜教。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM