張東偉
[摘 要] 本文主要介紹Oracle數據庫的內存組成,各部分內存如何分配與優化,包括SGA區、PGA區等。
[關鍵詞] Oracle 數據庫;內存分配;內存優化
doi : 10 . 3969 / j . issn . 1673 - 0194 . 2017. 13. 064
[中圖分類號] TP311.13 [文獻標識碼] A [文章編號] 1673 - 0194(2017)13- 0152- 03
1 數據庫系統介紹
數據庫技術產生于20世紀60年代末70年代初,其主要目的是有效地管理和存取大量的數據資源,研究如何存儲,使用和管理數據。數年來,數據庫技術發展迅速,應用廣泛。數據庫技術不僅應用于事務處理,并且進一步應用到情報檢索、人工智能、專家系統、計算機輔助設計等領域。
Oracle數據庫系統是Oracle(甲骨文)公司于1979年發布的世界上第一個關系數據庫管理系統。經過30多年的發展,Oracle公司也成為當今世界上最大的數據庫廠商和最大的商用軟件供應商,Oracle數據庫系統已經應用于各個領域,是當前市場占有率最高的數據庫產品,約為49%。在當今世界500強企業中,70%的企業使用的是Oracle數據庫,世界十大B2C公司全部使用Oracle數據庫,世界十大B2B公司中有9家使用的是Oracle數據庫。
2 Oracle數據庫內存基本組成
Oracle數據庫系統的內存包括兩部分:SGA和PGA。SGA即System Global Area系統全局區。一個數據庫實例對應一個SGA,SGA在數據庫實例啟動的時候被分配。SGA作為數據庫實例的基本組成,是一個非常大的內存空間,甚至可以占據物理內存的80%。PGA即Program Global Area程序全局區。一個服務進程啟動的時候就會分配一個PGA。在Oracle Instance中PGA可能會很多,例如啟動10個Server Process就會有10個PGA。
Oracle數據庫系統的使用場景一般為管理海量數據,而數據都是存儲在磁盤上的,為了提高存儲、訪問的效率,那么Oracle必然會在內存中開辟一塊很大的內存區域(內存的訪問速度比磁盤要快幾千倍甚至幾萬倍)。因此,Oracle是一個比較耗費內存的軟件,且大多消耗在SGA上。SGA的大小是可以配置的,隨著數據庫的負載加大,數據庫實例對內存的需求加大,那么SGA也會擴張甚至會把整個內存都消耗掉。因此,如何科學的分配Oracle數據庫系統的內存區對于數據庫系統來說是一個至關重要的問題。
3 Oracle數據庫內存優化
3.1 SGA區的內存分配管理
SGA包含以下幾大塊的基本內存:Shared Pool、Database Buffer Cache、Redo Log Buffer、Large Pool、Java Pool。其中Shared Pool、Database Buffer Cache、Redo Log Buffer是核心的內存區域,Large Pool和Java Pool是可選的。
Shared Pool的主要作用是存儲SQL解析后的內容。例如:發出一個SQL語句或命令讓數據庫執行,SQL在數據庫內部就需要被解析,建立執行計劃,然后按照執行計劃去執行,每個SQL語句都要被解析成原始操作去執行,解析好的SQL語句都會存儲在共享池中。在Oracle Instance中Shared Pool非常重要,它關系到數據庫的性能,共享池包含兩塊共享內存,這兩塊共享內存關系到數據庫的性能。
Library Cache中存儲的是經過編譯解析后的SQL和PL/SQL語句的內容。如果下次在執行同樣的SQL語句的時候,就不需要解析了,立即從Library Cache中獲取執行。Library Cache的SIZE決定著編譯解析SQL語句的頻度,從而決定了性能。
Data Dictionary就是存儲著數據庫的控制信息。為了提高訪問Data Dictionary的速度,此時需要一個緩存,需要的時候訪問內存即可。Data Dictionary Cache里面的信息包含了database files、tables、indexes、columns、users、privileges和其他的數據庫對象。數據字典是使用最頻繁的,幾乎所有的操作都需要到數據字典去查詢(例如:需要針對一個表進行操作,就需要到數據字典去查詢用戶對這個表是否具有訪問權限等等),它的大小是由Shared Pool來決定的。
Database Buffer Cache的任務主要是用于存儲數據文件中的數據,在Oracle中數據是存儲在磁盤上的,但訪問磁盤中的數據速度又會很慢,那么就需要將其中一部分的數據放入到內存中,提升訪問的速度。例如一個用戶去訪問一個表里面的記錄時,數據庫接收到這個請求后,他首先會在這個緩存中查找是否存在該數據庫表的記錄,如果有,則直接從內存中讀取該記錄返回給用戶,否則只能去磁盤上去讀取。很顯然,如果希望性能提高就需要提升Cache的命中率。Database Buffer Cache中存儲的是Data Blocks(數據塊)。
數據庫是處于經常改變狀態的,比如有時候事務失敗的需要回滾,就需要Redo Log Files來記錄數據庫的改變,如果想恢復數據庫文件就用Redo Log Files里面的內容進行恢復。Redo Log File在內存中有一個對應的Cache,它稱為Redo Log Buffer。每次對數據進行改變,在Redo Log里面就會有相應的一條記錄,這條記錄稱為Redo Entries,一條Redo Entries就可以恢復一次對數據庫的改變。Redo Log Buffer的SIZE由參數LOG_BUFFER來決定。
Large Pool主要用于處理一些額外的工作,比如說使用RMAN進行備份、進行并行處理,或者做一些I/O操作。Large Pool的SIZE由參數LARGE_POOL_SIZE來決定。
Oracle支持Java編程,例如支持Java編寫存儲過程,Java Pool的SIZE由參數JAVA_POOL_SIZE來決定。
由此可見,SGA是用于存儲數據庫信息的內存區,該信息為數據庫進程所共享。它包含Oracle 服務器的數據和控制信息,它是在Oracle服務器所駐留的計算機的實際內存中得以分配,如果實際內存不夠再往虛擬內存中寫。設置SGA的內存分配策略是整個數據庫系統內存管理的關鍵,理論上SGA可占操作系統物理內存的1/3-1/2。經研究測試發現,當SGA區達到系統可用內存的55%-58%時效果最佳,更有利于內存資源的充分利用與性能發揮。它的內存分配原則為:SGA+PGA+操作系統使用內存<總物理內存。SGA=(db_block_buffers*blocksize)+(shared_pool_size+large_pool_size+java_pool_size+log_buffers)+1MB
3.2 PGA程序全局區的內存分配管理
PGA:包含單個服務器進程或單個后臺進程的數據和控制信息,與幾個進程共享的SGA 正相反。PGA 是只被一個進程使用的區域,PGA 在創建進程時分配在終止進程時回收。我們先將參數PGA_AGGREGATE_TARGET的值設置為SGA的20%,然后在數據庫中運行有代表性的工作負荷、統計、檢查PGA運行情況,然后根據實際情況對其進行適當調整。PGA包括兩個分區,即Sort_area_size用于排序所占內存,Hash_area_size用于散列聯接,位圖索引。這兩個分區是為每個會話單獨分配的,在我們的服務器上除了OS + SGA,一定要考慮這兩部分。它的內存分配原則為:OS 使用內存+SGA+并發執行進程數*(sort_area_size+hash_ara_size+2M) < 0.7*總內存。