王文娟,王潤(rùn)中
(1.廣州南洋理工職業(yè)學(xué)院,廣州510900;2.Northern Alberta Institute of Technology,加拿大)
以O(shè)racle 數(shù)據(jù)庫(kù)產(chǎn)品享譽(yù)全球的Oracle 公司,在2013 年后成為繼Microsoft 后全球第二大軟件公司,而其中的數(shù)據(jù)庫(kù)產(chǎn)品Oracle 11g,又以其自動(dòng)內(nèi)存管理被認(rèn)為是內(nèi)存走向智能化的重要管理階段,是數(shù)據(jù)庫(kù)軟件發(fā)展的一個(gè)里程碑。Oracle 從可占OS 系統(tǒng)內(nèi)存的1/3 到1/2,直到占用80%的內(nèi)存,如此高占比物理內(nèi)存促使我們有必要在校企合作實(shí)訓(xùn)實(shí)驗(yàn)中探討Oracle 的內(nèi)存管理。根據(jù)工作負(fù)載情況,通過(guò)對(duì)SGA 和PGA 監(jiān)測(cè),在多種內(nèi)存管理方式下選擇不同的內(nèi)存管理方式并進(jìn)行各種參數(shù)進(jìn)行設(shè)置,并充分利用其智能化內(nèi)存管理特性,使得數(shù)據(jù)庫(kù)性能達(dá)到最優(yōu)。
在裝有Oracle 數(shù)據(jù)庫(kù)的計(jì)算機(jī)上,其內(nèi)存主要由SGA、PGA 和UGA 組成,如圖1 所示,通常講的Oracle的內(nèi)存管理,主要是對(duì)SGA 和PGA 這兩部分區(qū)域進(jìn)行管理。
當(dāng)Oracle 啟動(dòng)時(shí),首先使用的是靜態(tài)內(nèi)存管理,此時(shí)的內(nèi)存是按照SGA 內(nèi)預(yù)先配置好參數(shù)進(jìn)行內(nèi)在分配;當(dāng)實(shí)例啟動(dòng)時(shí),Oracle 會(huì)自動(dòng)分配SGA,當(dāng)關(guān)閉例程時(shí),Oracle 會(huì)自動(dòng)釋放SGA 所占用的空間;PGA 是在服務(wù)器進(jìn)程啟動(dòng)或創(chuàng)建時(shí)分配,并為服務(wù)器進(jìn)程所專用;UGA 則是為用戶進(jìn)程存儲(chǔ)會(huì)話狀態(tài)的。

圖1 Oracle內(nèi)存結(jié)構(gòu)
自動(dòng)管理模式是在Oracle 9i 開(kāi)始引入的,先是PGA 自動(dòng)管理,SGA 仍為手動(dòng)管理;在10g 時(shí)Oracle 推出了ASMM,實(shí)現(xiàn)了SGA 和PGA 內(nèi)部結(jié)構(gòu)的自調(diào)節(jié),即PGA 和SGA 均為自動(dòng)管理;進(jìn)入11g 之后,自動(dòng)內(nèi)存管理AMM 實(shí)現(xiàn)對(duì)SGA 和PGA 的規(guī)劃全部統(tǒng)籌,因而AMM 成為數(shù)據(jù)庫(kù)發(fā)展中的重要部分,這種對(duì)PGA和SGA 統(tǒng)一進(jìn)行自動(dòng)管理,從某種程度上來(lái)說(shuō)內(nèi)存管理逐漸的走向智能化。
SGA(System Global Area)是用于加載數(shù)據(jù)、對(duì)象并保存運(yùn)行狀態(tài)和數(shù)據(jù)庫(kù)控制信息的一塊內(nèi)存區(qū)域,在數(shù)據(jù)庫(kù)實(shí)例啟動(dòng)時(shí)進(jìn)行分配,大小通常SGA 與操作系統(tǒng)、內(nèi)存大小、CPU、同時(shí)登錄的用戶數(shù)有關(guān);在數(shù)據(jù)庫(kù)運(yùn)行過(guò)程中,內(nèi)存大小可以在線修改與自動(dòng)配置,這便是動(dòng)態(tài)內(nèi)存管理。
SGA 是一個(gè)共享的內(nèi)存結(jié)構(gòu),每個(gè)實(shí)例都有自己的SGA 區(qū)。當(dāng)多個(gè)用戶并發(fā)地連接到同一個(gè)實(shí)例后,這些用戶將共享此實(shí)例SGA 中的數(shù)據(jù)。圖2 是SGA的基本內(nèi)存結(jié)構(gòu),除了數(shù)據(jù)高速緩沖區(qū)(Data Buffer Cache)、重做日志緩沖區(qū)(Redo Log Buffer)、共享池(Shared Pool)、Java 池(Java Pool)、大型池(Large Pool)外,還包括三個(gè)子緩沖區(qū):保留緩沖區(qū)、循環(huán)緩沖區(qū)和非標(biāo)準(zhǔn)大小塊緩沖區(qū)。

圖2 SGA內(nèi)存結(jié)構(gòu)
Oracle 支持動(dòng)態(tài)SGA 特性,無(wú)需關(guān)閉實(shí)例,在無(wú)DBA 的干預(yù)的情況下,根據(jù)系統(tǒng)上的工作負(fù)載,就可以自動(dòng)調(diào)整數(shù)據(jù)高速緩沖區(qū)、共享池和大型池的大小。池可以進(jìn)行擴(kuò)展也可以進(jìn)行縮小,前者是為滿足自身增長(zhǎng)需求,后者則是滿足其他池的擴(kuò)展需求。
Oracle 從Oracle 9i 開(kāi)始支持動(dòng)態(tài)SGA 特性。ASMM(Automatic Shared Memory Management)的主要工作是讓DBA 不再需要手工設(shè)置shared pool、buffer pool 等若干內(nèi)存池的大小,而AMM 的引入,則使得Oracle 內(nèi)存管理更加靈活多樣,組合出來(lái)有5 種內(nèi)存管理形式,即自動(dòng)內(nèi)存管理,自動(dòng)共享內(nèi)存管理,手工共享內(nèi)存管理,自動(dòng)PGA(Program Global Area)管理,手動(dòng)PGA 管理方式。單擊“自動(dòng)內(nèi)存管理”禁用按鈕,并選擇“啟用自動(dòng)共享內(nèi)存管理”,DBA 可以在此頁(yè)中使數(shù)據(jù)庫(kù)自動(dòng)設(shè)置下的各SGA 組件的內(nèi)存達(dá)到最佳分配方式。如此實(shí)現(xiàn)AMM 和ASMM 的切換,從而實(shí)現(xiàn)內(nèi)存多種管理方式,具體內(nèi)存管理方式設(shè)置見(jiàn)表1 內(nèi)存管理方式設(shè)置表。
如果指定了MEMORY_TARGET 沒(méi)有指定MEMORY_MAX_TARGET,重啟后MEMORY_MAX_TARGET=MEMORY_TARGET。如果指定了MEMORY_MAX_TARGET 而沒(méi)有指定MEMORY_TARGET,重啟后MEMORY_TARGET 為0。

表1 內(nèi)存管理方式設(shè)置表
Oracle 10g 引入sga_target,可以自動(dòng)對(duì)SGA 進(jìn)行調(diào)整,且SGA 的總大小不能超過(guò)初始化參數(shù)SGA_MAX_SIZE 的設(shè)置,具體命令如下:
SQL>ALTERSYSTEMSETSGA_MAX_SIZE=***MSCOPE=SPFILE;
SQL>ALTER SYSTEM SET SGA_TARGET=***MSCOPE=SPFILE;
Oracle 11g 則對(duì)這SGA 和PGA 兩部分進(jìn)行綜合,引入memory_target,可以自動(dòng)調(diào)整所有的內(nèi)存,即自動(dòng)內(nèi)存管理。11g 里面引入了兩個(gè)成對(duì)的新參數(shù)——memory_target 和memory_max_target,這兩個(gè)參數(shù)讓SGA 和PGA 在總的內(nèi)存量?jī)?nèi)靈活自動(dòng)調(diào)整,在默認(rèn)情況下,sga_target 和pga_aggreargate,target 設(shè)置為零,也就是說(shuō)采用了新的自動(dòng)調(diào)整參數(shù)方式。MEMORY_TARGET 可被動(dòng)態(tài)調(diào)整,但要注意不可超過(guò)MEMORY_MAX_TARGET 的值。
注意,當(dāng)處在ASMM 狀態(tài)時(shí),設(shè)置SGA 各部分內(nèi)存參數(shù)的最小值限制;在處在AMM 狀態(tài)時(shí),若此時(shí)的數(shù)據(jù)庫(kù)使用了SPFILE,由于數(shù)據(jù)庫(kù)關(guān)閉后,系統(tǒng)會(huì)將上一次數(shù)據(jù)庫(kù)關(guān)閉時(shí)的內(nèi)存分配狀態(tài)記錄下來(lái),建議使用SPFILE。具體命令如下:
SQL>ALTER SYSTEM SET MEMORY_MAX_TARGET=***M SCOPE=SPFILE;
從一般意義上講SGA 越大系統(tǒng)的性能越好,但這兩個(gè)參數(shù)不宜設(shè)置過(guò)高,不應(yīng)超過(guò)系統(tǒng)實(shí)際內(nèi)存的1/2,否則在實(shí)例啟動(dòng)時(shí)可能會(huì)出現(xiàn)錯(cuò)誤。
與多個(gè)進(jìn)程共享的SGA 相反,PGA(Program Global Area)是只為一個(gè)用戶進(jìn)程服務(wù)的,其作用是保護(hù)會(huì)話信息、排序信息以及用戶的私有數(shù)據(jù)信息。只有該用戶的服務(wù)進(jìn)程能夠訪問(wèn)它自己的PGA 區(qū)。當(dāng)用戶進(jìn)程連接到Oracle 數(shù)據(jù)庫(kù)時(shí),創(chuàng)建一個(gè)會(huì)話并通過(guò)C語(yǔ)言的運(yùn)行時(shí)調(diào)用malloc()或memmap()來(lái)分配內(nèi)存,會(huì)話結(jié)束時(shí),PGA 被釋放。
對(duì)于這種只有操作系統(tǒng)進(jìn)程或線程專用的內(nèi)存,PGA 包含了工作區(qū)(SQL Work Areas)、會(huì)話區(qū)(Session Memory)和私有SQL 區(qū),而SQL Work Areas 又由sort area、hash area、bitmap merge area 組成如圖3 所示。

圖3 PGA內(nèi)存結(jié)構(gòu)
這些組件分工各有不同,Session Memory 主要存儲(chǔ)一些登錄的信息。Private SQL Area 分為永久區(qū)域(Persistent Area)和時(shí)區(qū)域(Runtime Area)。永久區(qū)域存儲(chǔ)綁定變量等信息,在游標(biāo)關(guān)閉時(shí)釋放;運(yùn)行時(shí)區(qū)域存放了SQL 語(yǔ)句運(yùn)行時(shí)的信息,如執(zhí)行查詢的狀態(tài)信息、查詢工作區(qū)(SQL Work Areas)等。不過(guò)對(duì)于共享服務(wù)器模式,Session 這部分內(nèi)存在SGA 中分配。
PGA 分兩種管理模式,一是手動(dòng)PGA 內(nèi)存管理,用于為用戶指定排序區(qū)和散列區(qū)所使用的內(nèi)存,且每個(gè)連接使用相同的內(nèi)存。二是自動(dòng)PGA 內(nèi)存管理,即只設(shè)置Oracle 可以使用的PGA 的總量,由Oracle 根據(jù)系統(tǒng)負(fù)載決定具體分配,可以動(dòng)態(tài)擴(kuò)大也可以回收。
根據(jù)表1,在11g 中要進(jìn)行手動(dòng)內(nèi)存管理時(shí),先關(guān)閉自動(dòng)內(nèi)存管理AMM,然后才能設(shè)置PGA 具體命令如下:
SQL>ALTER SYSTEM SET MEMORY_TARGET=0;
若PGA 設(shè)為自動(dòng)內(nèi)存管理,PGA_AGGREGATE_TARGET 設(shè)置為非0 值,具體命令如下:
SQL>ALTER SYSTEM SET PGA_AGGREGATE_TARGET=***M;
如果設(shè)置workarea_size_policy 為auto 則sort_area_size,hash_area_size 等參數(shù)不用被忽略;如果workarea_size_policy 為manual,則進(jìn)行sort_area_size,hash_area_size 等參數(shù)設(shè)置生效。
我們可以對(duì)圖2 所示的SGA 的各個(gè)組件均可進(jìn)行監(jiān)測(cè),可以根據(jù)監(jiān)測(cè)的情況調(diào)整各個(gè)組件參數(shù)的值,也可以直接根據(jù)工作任務(wù)進(jìn)行配置。
在進(jìn)行聯(lián)機(jī)事務(wù)處理時(shí),對(duì)于物理內(nèi)存16GB,根據(jù)Oracle 官方提供的使用經(jīng)驗(yàn),一般Oracle 所占物理內(nèi)存的80%分配給SGA,只給PGA 內(nèi)存設(shè)置20%,命令如下:
SQL>ALTER SYSTEM SET SGA_MAX_SIZE=10g SCOPE=SPFILE;
SQL>ALTER SYSTEM SET SGA_TARGET=10g SCOPE=SPFILE;
SQL>ALTER SYSTEM SET WORKAREA_SIZE_POLICY=AUTO SCOPE=BOYH;
SQL>ALTER SYSTEM SET PGA_AGGREGATE_TARGET=2000M SCOPE=BOYH;
但是通過(guò)對(duì)內(nèi)存監(jiān)測(cè),最后師生們普遍認(rèn)為SGA與PGA 的總和不宜超過(guò)總內(nèi)存的70%。
我們要做備份,需要使用大型池,此時(shí)數(shù)據(jù)緩沖區(qū)沒(méi)有大量的數(shù)據(jù),在自動(dòng)內(nèi)存管理模式下,自動(dòng)將縮小數(shù)據(jù)緩沖區(qū)并抽調(diào)該內(nèi)存為大型池服務(wù)。
不過(guò),此時(shí)SGA 中的有些池不受動(dòng)態(tài)大小調(diào)整的影響,例如非標(biāo)準(zhǔn)塊大小的緩沖池,以及KEEP 池或RECYCLE 池的非默認(rèn)塊大小。再有,就是日志緩沖區(qū)、數(shù)據(jù)高速緩沖區(qū)同樣可以不受內(nèi)存調(diào)整的影響。
在手工管理方式下,做備份一般對(duì)大型池設(shè)置較大一些,具體命令如下:
SQL>ALTER SYSTEM SET LARGE_POOL_SIZE=128M;
數(shù)據(jù)緩沖區(qū)用于緩存從數(shù)據(jù)文件中檢索出來(lái)的數(shù)據(jù)塊,它與查詢效率和更新數(shù)據(jù)的性能緊密相關(guān),通過(guò)使用如下命令查看情況:
SQL>SHOW PARAMETER db_cache_size;
如果db_cache_size 顯示為0,這并不意味著Oracle 沒(méi)有給實(shí)例分配了數(shù)據(jù)庫(kù)高速緩沖區(qū),而是在SGA在自動(dòng)管理模式。使用以下命令查看命中率:
SQL>select 1-((physical.value-direct.value-lobs.value)/logical.value)
2"Buffer Cache Hit Ratio"
3 from v$sysstat physical,v$sysstat direct,v$sysstat lobs,v$sysstatlogical
4 where physical.name='physical reads'
5 anddirect.name='physical reads direct'
6 andlobs.name='physical reads direct(lob)'
7 andlogical.name='session logical reads';
如果此時(shí)顯示命中率低于90%,要適度調(diào)整db_cache_size 的大小,命令下:
SQL>ALTER SYSTEM SET db_cache-size=1120M;