王潤中
(Gina Code School of Engineering and Computer Science, Concordia University,Canada)
最初我們接觸操作系統時,我們了解到的操作系統是管理計算機硬件與軟件資源的計算機程序,具有五大管理功能,其中之一就是存儲管理,之二就是進程管理,但是隨著Oracle的微機版的出現,從披露出來不多的內存和進程管理和在操作系統上所安裝的Oracle、其對內存的占用達到80%的情況,以及以數據特征進行存儲的方式上看,我們有必要探索操作系統與Oracle內存管理和進程管理并對其主要特性進行比較。
整個操作系統內核可以大致分成三個模塊,其中內存管理和進程管理分別對內存和CPU進行分配和調度,如圖1所示。內存是CPU直接存放處理數據的地方,是CPU與外部設備交換數據的地方,同時也是所有計算機程序的運行之所在。
對操作系統而言,當要進行數據處理時需要將相應的程序調入到內存中運行,此時系統要進行資源分配和調度,于是進程便成為這樣一個基本單位,負責程序及相關數據集合的一次運行活動,具有獨立運行、獨立分配資源、獨立接受調度的特點,如圖2所示。

圖1 內存管理與進程管理

圖2 進程的內容結構
操作系統管理著許多的進程,許多的進程由進程管理統一調度,包括創建與終止以及釋放所占資源,通過對進程的管理可以有效地提高CPU的利用率。每一個進程由進程控制模塊(PCB)、程序和數據集合組成。所有進程都必須占用一定數量的內存,內核的運行也是需要操作內存,而每個進程又要保持獨立性,這就需要虛擬內存來實現,每個進程有自己的虛擬內存,通過進程控制塊,按照時間片的方式,進程輪流執行,只有輪詢到自己的時候,才對應由物理內存來使用,其他時間就等待。
一般我們敘述的存儲管理方案主要包括分區存儲管理、分頁存儲管理、分段存儲管理、段頁式存儲管理以及虛擬存儲管理。分段就是將一個程序分成代碼段,數據段,堆棧段等,分頁存儲管理則是將一個進程的邏輯地址空間分成若干個大小相等的片,稱為頁,并為各頁加以編號,而分段分頁就是將這些段,例如代碼段分成均勻的小塊,圖3所示,通過段表和頁表,頁內偏移找到程序的物理地址。分段的作業地址空間是二維的,程序員在標識一個地址時,既需給出段名,又需給出段內地址。分頁的作業地址空間是維一的,即單一的線性空間,程序員只須利用一個記憶符,即可表示一地址。現代的大多數計算機系統,都支持非常大的邏輯地址空間(232~264)。在這樣的環境下,頁表就變得非常大,要占用相當大的內存空間。如此復雜的存儲管理已經成為阻礙網絡存儲廣泛應用的一個重要原因。

圖3 段頁式存儲管理
很多的書籍和文章中都直接給出了如圖4所示的Oracle的內存和進程結構圖,這張圖展示的Oracle內存結構包含一系列組件,用戶進程、服務進程等。當客戶端向服務器發送連接請求時,服務器在監聽到客戶端要求后,生成一個Server Process來代理用戶的請求,然后向服務器進程實例發起連接,創建會話,此時PGA(程序全局區)分配內存,在這個過程中,一個進程一個PGA。
當用戶進程執行一個查詢語句時,用戶進程先將信息存儲到UGA(用戶全局區)中,語句本身被解析為

圖4 Oracle內存和進程結構圖
ASCII碼,生成hash_value,在PGA中匹配,進行快速解析,然后傳遞給實例,在SGA(系統全局區)的共享池中處理這條語句,在數據緩沖區中判斷是否有所需要的塊,如果沒有從磁盤讀入,然后undo緩存塊會對該塊做鏡像,讀鏡像中的數據得到行的結果返回給用戶,用戶看到執行的結果。無論在自動內存管理模式還是手動內存管理模式,Oracle通常都會將內存的70%-80%分配給SGA,而PGA僅達到20%。
Oracle給出的不僅是清晰的內存管理與操作的功能視圖,也是將存放在內存的各種處理要求不同的數據與其操作的相應進程的邏輯圖,這對內存的管理比傳統方式的操作系統更為有效,進而Oracle也有了自動內存管理模式。其次,PGA是將用戶的請求分解為公有和私有部分,對于數據的請求全部放在SGA中,這種公私分離的模式提高了內存的使用效率,這使得即便在PC上,其查詢的能力也能達到TB的數量級。
首先相似的地方是在內存的分配上,無論操作系統還是Oracle均是通過功能相似的進程分配內存的。在操作系統在啟動時,例如Linux,需要加載內核映像到內存中,內核映像并不是一個可執行的內核,而是一個壓縮過的內核映像。必須先啟動例程實現少量硬件設置后,對內核映像中包含的內核進行解壓縮,然后將其放入高端內存中。
分配內存的時候,系統先是安排內核內存空間,這里存放各個內核進程工作的數據和系統日志數據,然后系統為用戶分配用以存放用戶進程的內存。無論是內核進程,還是用戶進程,Linux對內存的分配都是基于進程的。
當啟動Oracle一個數據實例時,Oracle數據庫系統會啟動多個后臺進程,這些后臺進程負責不同的工作,都需要一定的內存存放工作時的永久數據和臨時數據,用以完成數據庫數據文件、日志文件、參數文件等的讀寫操作。
當客戶端請求連接Oracle數據庫,Oracle數據庫也會動態產生一個服務器進程為該客戶端服務,客戶要對數據庫的各種操作,包括查增刪改、事務提交回滾等,均委派相應的服務器進程統一處理。每一次客戶端與服務器的連接,均包括多個會話,而每次會話,系統都會分配不同的會話內存空間,用于存放不同會話的不同數據。無論是后臺進程,還是服務進程,Oracle對內存的分配都是基于進程的。
補充一點,對于不同的會話,無論操作系統和還是Oracle都是基于用戶的。用戶是根據所獲取權限,對操作系統或數據庫資源對象進行不同級別的使用和處理,更好地維護了數據的安全。
操作系統與Oracle不同的地方,突出的是操作系統通常使用的虛擬內存管理Oracle是沒有的。例如在Linux中,每個用戶進程都可以有4GB的虛擬空間,為了更好地管理這部分虛擬空間,Linux定義了虛擬段,虛擬段是某個進程的一段連續的虛擬空間,一個進程通常占用幾個虛擬段。虛擬段不僅代表一段內存區間,也可以對應于一個文件、共享內存或者對換設備。由于幾乎所有的操作系統都支持虛擬內存,不可避免的是操作系統將Oracle的SGA整個作為虛擬內存。
其次,內存區域是否共享是操作系統與Oracle的重要區別,操作系統中并不存在一個系統全局內存區供內核進程和用戶進程共享,相反,操作系統中的進程在內存區域上是相對獨立的,不同的進程維護不同的內存區。在Oracle中存在SGA,為系統分配著一組共享的內存結構,包含一個數據庫實例的數據和控制信息。在一個數據實例中,可以有多個后臺進程和服務器進程共享系統全局區中的數據;此外,Oracle不僅僅有共享的內存,而且也有PGA,跟操作系統進程一樣,該內存區是專門為某以Oracle服務器進程或者后臺進程服務的。
第三,Oracle從Oracle 9i開始引入自動內存管理ASMM支持動態SGA特性,使得Oracle內存管理更加靈活多樣,通過組合有5種內存管理形式,即自動內存管理,自動共享內存管理,手工共享內存管理,自動PGA(Program Global Area)管理以及手動PGA管理方式。單擊“自動內存管理”禁用按鈕,并選擇“啟用自動共享內存管理”,DBA可不再通過手工設置shared pool、buffer pool、db_cache_size等若干內存池的大小的情況下,數據庫自動完成并達到各SGA組件的最佳內存配置分配方式。
傳統的概念上講,存儲管理和進程管理是操作系統的五個職能中的兩個,但從Oracle上我們直接看到的在上述兩個區域Oracle同樣執行這樣的功能,比起一級一級的頁表進行繁瑣的尋址,Oracle給出了清晰的內存管理與操作的功能視圖,便于程序員編寫代碼;其次Oracle將用戶的請求分解為公有和私有部分,且大部分的共享數據的請求全部放在占有大多內存的SGA中,這種公私分離的模式提高了內存的使用效率;第三,Oracle的ASMM內存管理可以智能化分配SGA組件的內存。最后,Oracle的整個SGA直接映射為操作系統將虛擬內存,獨到之處體現了其在操作系統下的類似自治管理方式的優勢,值得借鑒。