時(shí)間:2024-03-13 13:57作者:下載吧人氣:18
對(duì)于數(shù)據(jù)庫(kù)引擎來(lái)說(shuō),內(nèi)存是一個(gè)性能提升的重要解決手段。把數(shù)據(jù)緩存起來(lái),可以避免在查詢(xún)或更新數(shù)據(jù)時(shí)花費(fèi)多余的時(shí)間,而這時(shí)間通常是從磁盤(pán)獲取數(shù)據(jù)時(shí)用來(lái)等待磁盤(pán)尋址的。把執(zhí)行計(jì)劃緩存起來(lái),可以避免重復(fù)分析執(zhí)行計(jì)劃時(shí)帶來(lái)額外的CPU及各種資源的開(kāi)銷(xiāo)。通過(guò)在內(nèi)存中開(kāi)辟查詢(xún)內(nèi)存空間,可以迅速地完成排序、哈希等計(jì)算,達(dá)到快速返回運(yùn)算結(jié)果的目的。若沒(méi)有足夠的內(nèi)存空間,數(shù)據(jù)庫(kù)引擎將無(wú)法快速地響應(yīng)用戶(hù)的請(qǐng)求。
SQL Server存儲(chǔ)引擎本身是一個(gè)Windows下的進(jìn)程,所以SQL Server使用內(nèi)存和其它Windows進(jìn)程一樣,都需要向Windows申請(qǐng)內(nèi)存(通過(guò)VirtualAlloc之類(lèi)的API向Windows申請(qǐng)內(nèi)存)。
內(nèi)存芯片提供的物理存儲(chǔ)空間,能被CPU直接訪(fǎng)問(wèn),訪(fǎng)問(wèn)速度快,易丟失。內(nèi)存性能指標(biāo)GB/s,ns(納秒),前者是吞吐量,后者是響應(yīng)時(shí)間。磁盤(pán)性能指標(biāo)MB/s,us(微秒),從兩者對(duì)比就能看出內(nèi)存訪(fǎng)問(wèn)速度是遠(yuǎn)優(yōu)于磁盤(pán)的。
物理內(nèi)存容量是有限的,如果所有進(jìn)程都直接使用有限的物理內(nèi)存,那新的進(jìn)程將無(wú)法為他們找到任何物理內(nèi)存,那么物理內(nèi)存將容易成為瓶頸。所以Windows會(huì)授予每個(gè)進(jìn)程一個(gè)虛擬地址空間(Virtual Address Space,VAS),通過(guò)VAS建立應(yīng)用程序與物理內(nèi)存的橋梁。
是指一個(gè)應(yīng)用程序能夠申請(qǐng)?jiān)L問(wèn)的最大地址空間。VAS作為中間的抽象層的,不是所有的請(qǐng)求都直接映射到物理內(nèi)存,它首先映射到VAS,然后映射到物理內(nèi)存。
而兩個(gè)進(jìn)程可以共用一個(gè)VAS,而VAS的大小取決于CPU架構(gòu),具體請(qǐng)看下面表格:
OS Type |
Kernel Model (內(nèi)核模式) |
User Model (用戶(hù)模式) |
Total |
32位系統(tǒng) |
2GB |
2GB |
4GB |
64位系統(tǒng) |
8TB |
8TB |
16TB |
VAS有兩種內(nèi)存模式,Kernel Model和User Model。Kernel Model下的VAS是供Windows系統(tǒng)進(jìn)程使用,而User Model下的VAS是供用戶(hù)進(jìn)程使用。
由表格可知,32位Windows系統(tǒng)應(yīng)用程序可以訪(fǎng)問(wèn)最大2GB的VAS,64Windows位系統(tǒng)可以訪(fǎng)問(wèn)最大8TB的VAS。這意味著在32位Windows系統(tǒng)中一個(gè)word文檔進(jìn)程跟一個(gè)SQL Server進(jìn)程能得到最大2GB的VAS是一樣的。因此,從理論上講,這意味著任何應(yīng)用程序進(jìn)程在32位Windows系統(tǒng)上都將共享最大限度的2 G的VAS。
VMM是負(fù)責(zé)把物理內(nèi)存在系統(tǒng)中所有需要內(nèi)存的進(jìn)程之間作共享,必要時(shí)會(huì)從VAS回收物理內(nèi)存,把數(shù)據(jù)存儲(chǔ)到頁(yè)面文件上面去,保證數(shù)據(jù)永不丟失。當(dāng)進(jìn)程需要內(nèi)存時(shí),VMM會(huì)從頁(yè)面文件中查找數(shù)據(jù),并將這數(shù)據(jù)寫(xiě)入一部分空閑內(nèi)存當(dāng)中,然后將新頁(yè)面映射到需要操作的VAS當(dāng)中。
SQL Server 2012對(duì)內(nèi)存管理這塊跟SQL Server 2008還是有比較大的區(qū)別的,參考一些資料,下面我們來(lái)看看兩者具體架構(gòu)。
SQL Server 2008 R2:
SQL Server 2012:
名詞術(shù)語(yǔ)
為了更加清楚了解Buffer Pool,我們先來(lái)了解下 SQL Server的所需要的內(nèi)存有哪些,其中包括SQL Server服務(wù)(sqlserver.exe)和其它一些組件所占用的內(nèi)存,例如SQL Server代理程序(sqlagent.exe), SQL Server復(fù)制代理程序、SQL Server報(bào)表服務(wù)(ReportingServicesService.exe)、SQL Server Analysis Services(msmdsrv.exe)、SQL Server Integration Services(MsDtsSrvr.exe),和SQL Server 全文搜索(msftesql.exe)。
在一臺(tái)運(yùn)行SQL Server的服務(wù)器上,運(yùn)行著sqlserver服務(wù)(sqlserver.exe)和其它一些組件。在sqlserver服務(wù)(sqlserver.exe)獲取到的內(nèi)存中,又分為2大塊:一部分為Buffer Pool,另一部分為非Buffer Pool,舊稱(chēng)MemToReserve(默認(rèn)sqlserver.exe給它預(yù)留了256MB)。下表為這兩部分內(nèi)存各自的用途:
SQL Server 進(jìn)程所占內(nèi)存 |
||
Buffer Pool EXEC sp_configure N'min server memory EXEC sp_configure N'max server memory |
非Buffer Pool(即MemToReserve) (默認(rèn)為256MB), 可以sqlserver.exe啟動(dòng)時(shí)加-g參數(shù),預(yù)留足夠內(nèi)存(預(yù)留內(nèi)存大小=256MB+工作線(xiàn)程數(shù)*512KB) |
|
Buffer Pool中主要存放之前查詢(xún)中的數(shù)據(jù)頁(yè),和索引頁(yè)。然后根據(jù)它自已的算法,自動(dòng)清理過(guò)期過(guò)訪(fǎng)問(wèn)或效率低下的頁(yè)。 |
SQL Server工作線(xiàn)程 |
占用不多 |
分布式查詢(xún)引用的OLE DB訪(fǎng)問(wèn)接口 |
如操作鏈接服務(wù)器 |
|
備份還原 |
維護(hù)計(jì)劃或者T-SQL備份恢復(fù) |
|
擴(kuò)展過(guò)程 |
如sp_或sys開(kāi)頭的系統(tǒng)存儲(chǔ)過(guò)程,sp_OACreate 存儲(chǔ)過(guò)程 |
|
多頁(yè)的分配器SQL Server內(nèi)存管理器 |
如.net framework程序(它們連接sqlserver的網(wǎng)絡(luò)包大小為8K, sqlserver默認(rèn)網(wǎng)絡(luò)包大小為4k) |
|
.DLL文件 |
|
|
SQL Server CLR的Microsoft COM對(duì)象 |
這塊內(nèi)存是<=8kb的存儲(chǔ),適用于sql server 2008及以前,屬于Buffer Pool緩沖池來(lái)分配。有存儲(chǔ)數(shù)據(jù)頁(yè)面,Consumer功能組件。
這塊內(nèi)存是>8kb的存儲(chǔ),適用于sql server 2008及以前,不屬于Buffer Pool緩沖池來(lái)分配, 有存儲(chǔ)Consumer功能組件, 第三方代碼, Threads線(xiàn)程。
這個(gè)適用于sql server 2012及以上,整合了single-page,multi-page統(tǒng)稱(chēng)any size page。
它來(lái)統(tǒng)一響應(yīng)SQL Server 內(nèi)部各種組件內(nèi)存申請(qǐng)的請(qǐng)求。因?yàn)檫@個(gè)原因,在SQL Server 2012里面,max server memory 不再像以前的版本那樣,只控制buffer pool的大小,也包括那些大于8kb 的內(nèi)存請(qǐng)求。也就是,max server memory能夠更準(zhǔn)確地控制SQL Server 的內(nèi)存使用了。
從內(nèi)存架構(gòu)我們可以看到有page reservation需預(yù)先申請(qǐng)的內(nèi)存,有momory objects從windows api申請(qǐng)的內(nèi)存,有clr第三方申請(qǐng)的內(nèi)存。
內(nèi)存使用分類(lèi)
(1)Database Cache(數(shù)據(jù)頁(yè)面緩沖區(qū))
存放數(shù)據(jù)頁(yè)面的緩沖區(qū)。SQL Server數(shù)據(jù)庫(kù)里的數(shù)據(jù)都是以8KB為一個(gè)頁(yè)面存儲(chǔ)。當(dāng)有用戶(hù)需要使用到這個(gè)頁(yè)面上存儲(chǔ)的數(shù)據(jù)時(shí),SQL Server會(huì)把整個(gè)頁(yè)面都調(diào)入內(nèi)存,供用戶(hù)使用。所以8KB是數(shù)據(jù)訪(fǎng)問(wèn)的最小單元。當(dāng)用戶(hù)修改了某個(gè)頁(yè)面上的數(shù)據(jù)時(shí),SQL Server會(huì)在內(nèi)存中將這個(gè)頁(yè)面修改,但是不會(huì)立刻將這個(gè)頁(yè)面寫(xiě)回磁盤(pán),而是等到后面的Checkpoint或Lazy Write的時(shí)候集中處理。
(2)各類(lèi)Consumer
SQL Server的很多功能組件,都必須要申請(qǐng)內(nèi)存來(lái)完成它們的任務(wù)。這些統(tǒng)稱(chēng)為“Consumer”。常見(jiàn)有如下:
(3)線(xiàn)程內(nèi)存
SQL Server會(huì)為每個(gè)進(jìn)程內(nèi)的每個(gè)線(xiàn)程分配0.5MB的內(nèi)存,以存放線(xiàn)程的數(shù)據(jù)結(jié)構(gòu)和相關(guān)信息。
(4)第三方代碼申請(qǐng)的內(nèi)存(COM,XP…)
在SQL Server的進(jìn)程里,會(huì)運(yùn)行一些非SQL Server自身的代碼。例如,用戶(hù)定義的CLR或者Extended Stored Procedure代碼,Linked Server需要加載的數(shù)據(jù)連結(jié)驅(qū)動(dòng),調(diào)用SQL Mail功能需要加載的MAPI動(dòng)態(tài)庫(kù)等。這些代碼也會(huì)申請(qǐng)內(nèi)存,會(huì)算在SQL Server自己都不知道。
有些SQL Server內(nèi)存的申請(qǐng)方式,是預(yù)先Reserve一塊大的內(nèi)存,然后在使用的時(shí)候一小塊一小塊地Commit。而另外的內(nèi)存申請(qǐng)則直接從空間里Commit。在SQL Server里,把后一種方式叫Stolen。
在SQL Server里,對(duì)Database Cache,SQL Server會(huì)先Reserve,再Commit。其他的所有內(nèi)存使用,基本都是直接Commit,都是“Stolen”。要重申的是,Stolen內(nèi)存也是正常使用的內(nèi)存,不是泄漏掉的內(nèi)存。
之所以要把這兩種分開(kāi),是因?yàn)镾QL Server不會(huì)對(duì)Stolen的內(nèi)存使用AWE功能。也就是說(shuō),AWE擴(kuò)展出去的內(nèi)存,只能用來(lái)存放Database Cache。其他內(nèi)存還要在原來(lái)的那2GB里想辦法。
對(duì)于SQL Server自己申請(qǐng)的內(nèi)存,有兩種內(nèi)存申請(qǐng)單位。
小于等于8KB一個(gè)單位內(nèi)存申請(qǐng),SQL Server就分配一個(gè)8KB頁(yè)面。所有這些頁(yè)面都集中管理,這塊內(nèi)存被稱(chēng)為Buffer Pool。一次一個(gè)頁(yè)面的這種分配稱(chēng)為Single Page Allocation。
對(duì)于大于8KB為單位的內(nèi)存申請(qǐng),SQL Server把它們集中在另外一個(gè)區(qū)域,稱(chēng)為Multi-Page Allocation(舊稱(chēng)MemToLeave)。而這種分配稱(chēng)為Multi-Page Allocation。
類(lèi)型 |
Database Cache |
Consumer |
3rh Party Code |
Threads |
Reserved/Commit |
是 |
一般不是 |
一般不是 |
不是 |
Stolen |
不是 |
是 |
是 |
是 |
Buffer Pool (Single Page) |
所有 |
絕大部分 |
沒(méi)有 |
沒(méi)有 |
MemToLeave(Multi-Page) |
沒(méi)有 |
一小部分 |
所有 |
所有 |
這里的一個(gè)例外是運(yùn)行在SQL Server進(jìn)程里的CLR代碼所申請(qǐng)的內(nèi)存。這部分內(nèi)存像第三方代碼一樣,也是使用MemToLeave的內(nèi)存。但是,CLR可能也會(huì)用Reserve-Commit的方式申請(qǐng)內(nèi)存。所以MemToLeave的內(nèi)存也并不是都是Stolen的。
根據(jù)SQL Server內(nèi)存架構(gòu)圖,我們可以知道,在2012版本上,Single Page Allocation跟Multi-Page Allocation合并為Any Size Page Allocation了。而max server memory控制的不但是 Buffer Pool內(nèi)存大小,而是所有大于等于小于8KB的內(nèi)存請(qǐng)求。
如圖:
比如我設(shè)置最小服務(wù)器內(nèi)存為8G,重新啟動(dòng)下SQL Server (MSSQLSERVER)服務(wù),再使用dmv來(lái)查看當(dāng)前實(shí)例的總內(nèi)存空間,以及占用內(nèi)存空間:
–Target Server Memory (KB)最多能申請(qǐng)的內(nèi)存量
–Total Server Memory (KB)目前使用了多少內(nèi)存量
網(wǎng)友評(píng)論