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