溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Oracle內(nèi)存和架構(gòu)知識(shí)點(diǎn)有哪些

發(fā)布時(shí)間:2021-12-22 09:52:51 來(lái)源:億速云 閱讀:134 作者:iii 欄目:關(guān)系型數(shù)據(jù)庫(kù)

本篇內(nèi)容介紹了“Oracle內(nèi)存和架構(gòu)知識(shí)點(diǎn)有哪些”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

Oracle的內(nèi)存配置與oracle性能息息相關(guān)。關(guān)于內(nèi)存的配置,是最影響Oracle性能的配置。內(nèi)存還直接影響到其他兩個(gè)重要資源的消耗:CPU和IO. 

先看Oracle內(nèi)存存儲(chǔ)的主要內(nèi)容是什么:

程序代碼(PLSQL、Java);

關(guān)于已經(jīng)連接的會(huì)話的信息,包括當(dāng)前所有活動(dòng)和非活動(dòng)會(huì)話;

程序運(yùn)行時(shí)必須的相關(guān)信息,例如查詢計(jì)劃;

Oracle進(jìn)程之間共享的信息和相互交流的信息,例如鎖;

那些被永久存儲(chǔ)在外圍存儲(chǔ)介質(zhì)上,被cache在內(nèi)存中的數(shù)據(jù)(如redo log條目,數(shù)據(jù)塊)。

每個(gè)Oracle數(shù)據(jù)庫(kù)都是由Oracle Instance(實(shí)例)與數(shù)據(jù)庫(kù)(數(shù)據(jù)文件,控制文件、重做日志文件)組成,其中所謂實(shí)例就是用戶同數(shù)據(jù)庫(kù)交互的媒介,用戶通過(guò)于一個(gè)實(shí)例相連來(lái)操作數(shù)據(jù)庫(kù)。而實(shí)例又是由統(tǒng)一的內(nèi)存結(jié)構(gòu)(SGA,PGA,UGA)和一批內(nèi)存駐留進(jìn)程組成。實(shí)例在操作系統(tǒng)中用ORACLE_SID來(lái)標(biāo)識(shí),在Oracle中用參數(shù)INSTANCE_NAME來(lái)標(biāo)識(shí), 它們兩個(gè)的值是相同的。數(shù)據(jù)庫(kù)啟動(dòng)時(shí),系統(tǒng)首先在服務(wù)器內(nèi)存中分配系統(tǒng)全局區(qū)(SGA), 構(gòu)成了Oracle的內(nèi)存結(jié)構(gòu),然后啟動(dòng)若干個(gè)常駐內(nèi)存的操作系統(tǒng)進(jìn)程,即組成了Oracle的 進(jìn)程結(jié)構(gòu),內(nèi)存區(qū)域和后臺(tái)進(jìn)程合稱為一個(gè)Oracle實(shí)例。

一. SGA 

SGA是一組為系統(tǒng)分配的共享的內(nèi)存結(jié)構(gòu),可以包含一個(gè)數(shù)據(jù)庫(kù)實(shí)例的數(shù)據(jù)或控制信息。如果多個(gè)用戶連接到同一個(gè)數(shù)據(jù)庫(kù)實(shí)例,在實(shí)例的SGA中,數(shù)據(jù)可以被多個(gè)用戶共享。   當(dāng)數(shù)據(jù)庫(kù)實(shí)例啟動(dòng)時(shí),SGA的內(nèi)存被自動(dòng)分配;當(dāng)數(shù)據(jù)庫(kù)實(shí)例關(guān)閉時(shí),SGA內(nèi)存被回收。  SGA是占用內(nèi)存最大的一個(gè)區(qū)域,同時(shí)也是影響數(shù)據(jù)庫(kù)性能的重要因素。

SGA區(qū)是可讀寫(xiě)的。所有登錄到實(shí)例的用戶都能讀取SGA中的信息,而在oracle做執(zhí)行操作時(shí),服務(wù)進(jìn)程會(huì)將修改的信息寫(xiě)入SGA區(qū)。

SGA主要包括了以下的數(shù)據(jù)結(jié)構(gòu):

數(shù)據(jù)緩沖(Buffer Cache)

重做日志緩沖(Redo Log Buffer)

共享池(Shared Pool)

Java池(Java Pool)

大池(Large Pool)

流池(Streams Pool --- 10g以后才有)

數(shù)據(jù)字典緩存(Data Dictionary Cache)

其他信息(如數(shù)據(jù)庫(kù)和實(shí)例的狀態(tài)信息)

SQL> show sga

Total System Global Area  612368384 bytes

Fixed Size                  1250428 bytes

Variable Size             192940932 bytes

Database Buffers          411041792 bytes

Redo Buffers                7135232 bytes

SGA 中的數(shù)據(jù)字典緩存 和其他信息 會(huì)被實(shí)例的后臺(tái)進(jìn)程所訪問(wèn),它們?cè)趯?shí)例啟動(dòng)后就固定在SGA中了,而且不會(huì)改變,所以這部分又稱為固定SGA(Fixed SGA)。這部分區(qū)域的大小一般小于100K。

Shared Pool、Java Pool、Large Pool和Streams Pool這幾塊內(nèi)存區(qū)的大小是相應(yīng)系統(tǒng)參數(shù)設(shè)置而改變的,所以有通稱為可變SGA(Variable SGA)。

通過(guò)下面的語(yǔ)句查詢

SQL> show parameter sga

NAME                  TYPE        VALUE

------------------------------------ ----------- -------

lock_sga                boolean     FALSE

pre_page_sga            boolean     FALSE

sga_max_size            big integer  584M

sga_target               big integer  584M

先對(duì)這幾個(gè)參數(shù)做一下說(shuō)明:

SQL> select name,value ,ISSYS_MODIFIABLE from v$parameter where name like 'sga%';

NAME            VALUE           ISSYS_MOD

--------------- --------------- ---------

sga_max_size    612368384       FALSE

sga_target      612368384       IMMEDIATE


如果ISSYS_MODIFIABLE 返回的是false,說(shuō)明該參數(shù)無(wú)法用alter system語(yǔ)句動(dòng)態(tài)修改,需要重啟數(shù)據(jù)庫(kù)。

所以sga_max_size 是不可以動(dòng)態(tài)調(diào)整的。但是我們可以對(duì)sga_target 進(jìn)行動(dòng)態(tài)的調(diào)整。 

SGA_MAX_SIZE:

SGA區(qū)包括了各種緩沖區(qū)和內(nèi)存池,而大部分都可以通過(guò)特定的參數(shù)來(lái)指定他們的大小。但是,作為一個(gè)昂貴的資源,一個(gè)系統(tǒng)的物理內(nèi)存大小是有限。盡管對(duì)于CPU的內(nèi)存尋址來(lái)說(shuō),是無(wú)需關(guān)系實(shí)際的物理內(nèi)存大小的,但是過(guò)多的使用虛擬內(nèi)存導(dǎo)致page in/out,會(huì)大大影響系統(tǒng)的性能,甚至可能會(huì)導(dǎo)致系統(tǒng)crash。所以需要有一個(gè)參數(shù)來(lái)控制SGA使用虛擬內(nèi)存的最大大小,這個(gè)參數(shù)就是SGA_MAX_SIZE。

當(dāng)實(shí)例啟動(dòng)后,各個(gè)內(nèi)存區(qū)只分配實(shí)例所需要的最小大小,在隨后的運(yùn)行過(guò)程中,再根據(jù)需要擴(kuò)展他們的大小,而他們的總和大小受到了SGA_MAX_SIZE的限制。

當(dāng)試圖增加一個(gè)內(nèi)存的大小,并且如果這個(gè)值導(dǎo)致所有內(nèi)存區(qū)大小總和大于SGA_MAX_SIZE時(shí),oracle會(huì)提示錯(cuò)誤,不允許修改。

當(dāng)然,如果在設(shè)置參數(shù)時(shí),指定區(qū)域?yàn)閟pfile時(shí)(包括修改SGA_MAX_SIZE本身),是不會(huì)受到這個(gè)限制的。這樣就可能出現(xiàn)這樣的情況,在spfile中,SGA各個(gè)內(nèi)存區(qū)設(shè)置大小總和大于SGA_MAX_SIZE。這時(shí),oracle會(huì)如下處理:當(dāng)實(shí)例再次啟動(dòng)時(shí),如果發(fā)現(xiàn)SGA各個(gè)內(nèi)存總和大于SGA_MAX_SIZE,它會(huì)將SGA_MAX_SIZE的值修改為SGA各個(gè)內(nèi)存區(qū)總和的值。

SGA所分配的是虛擬內(nèi)存,但是,在我們配置SGA時(shí),一定要使整個(gè)SGA區(qū)都在物理內(nèi)存中,否則,會(huì)導(dǎo)致SGA頻繁的頁(yè)入/頁(yè)出,會(huì)極大影響系統(tǒng)性能。

對(duì)于OLTP系統(tǒng),一般的建議是將SGA_MAX_SIZE 設(shè)為物理內(nèi)存的60%,PGA 設(shè)為20%。 但是現(xiàn)在服務(wù)器內(nèi)存是相當(dāng)大的。 幾百G的內(nèi)存隨處可見(jiàn)。60%也就是幾百G內(nèi)存。 顯然這樣也是不合適的。 所以要根據(jù)自己系統(tǒng)來(lái)設(shè)定設(shè)定這個(gè)值。這個(gè)也就所說(shuō)的DBA的經(jīng)驗(yàn)。 這是是需要經(jīng)驗(yàn)的積累。 

下表的幾個(gè)數(shù)值供參考。

系統(tǒng)內(nèi)存

SGA_MAX_SIZE值

1G

400-500M

2G

1G

4G

2500M

8G

5G

SGA的實(shí)際大小可以通過(guò)以下公式估算:

SGA實(shí)際大小 = DB_CACHE_SIZE + DB_KEEP_CACHE_SIZE + DB_RECYCLE_CACHE_SIZE + DB_nk_CACHE_SIZE + SHARED_POOL_SIZE + LARGE_POOL_SIZE + JAVA_POOL_SIZE + STREAMS_POOL_SIZE(10g中的新內(nèi)存池) + LOG_BUFFERS+11K(Redo Log Buffer的保護(hù)頁(yè)) + 1MB + 16M(SGA內(nèi)部?jī)?nèi)存消耗,適合于9i及之前版本)

PRE_PAGE_SGA:

oracle實(shí)例啟動(dòng)時(shí),會(huì)只載入各個(gè)內(nèi)存區(qū)最小的大小。而其他SGA內(nèi)存只作為虛擬內(nèi)存分配,只有當(dāng)進(jìn)程touch到相應(yīng)的頁(yè)時(shí),才會(huì)置換到物理內(nèi)存中。我們可以通過(guò)設(shè)置PRE_PAGE_SGA參數(shù),讓實(shí)例一啟動(dòng)后,所有SGA都分配到物理內(nèi)存。

這個(gè)參數(shù)的默認(rèn)值為FALSE,即不將全部SGA置入物理內(nèi)存中。當(dāng)設(shè)置為T(mén)RUE時(shí),實(shí)例啟動(dòng)會(huì)將全部SGA置入物理內(nèi)存中。它可以使實(shí)例啟動(dòng)達(dá)到它的最大性能狀態(tài),但是,啟動(dòng)時(shí)間也會(huì)更長(zhǎng)(因?yàn)闉榱耸顾蠸GA都置入物理內(nèi)存中,oracle進(jìn)程需要touch所有的SGA頁(yè))。

SQL> alter system set pre_page_sga=true scope=spfile;

LOCK_SGA

為了保證SGA都被鎖定在物理內(nèi)存中,而不必頁(yè)入/頁(yè)出,可以通過(guò)參數(shù)LOCK_SGA來(lái)控制。這個(gè)參數(shù)默認(rèn)值為FALSE,當(dāng)指定為T(mén)RUE時(shí),可以將全部SGA都鎖定在物理內(nèi)存中。當(dāng)然,有些系統(tǒng)不支持內(nèi)存鎖定,這個(gè)參數(shù)也就無(wú)效了。

SGA_TARGET

Oracle10g中引入的一個(gè)非常重要的參數(shù)。在10g之前,SGA的各個(gè)內(nèi)存區(qū)的大小都需要通過(guò)各自的參數(shù)指定,并且都無(wú)法超過(guò)參數(shù)指定大小的值,盡管他們之和可能并沒(méi)有達(dá)到SGA的最大限制。此外,一旦分配后,各個(gè)區(qū)的內(nèi)存只能給本區(qū)使用,相互之間是不能共享的。拿SGA中兩個(gè)最重要的內(nèi)存區(qū)Buffer Cache和Shared Pool來(lái)說(shuō),它們兩個(gè)對(duì)實(shí)例的性能影響最大,但是就有這樣的矛盾存在:在內(nèi)存資源有限的情況下,某些時(shí)候數(shù)據(jù)被cache的需求非常大,為了提高buffer hit,就需要增加Buffer Cache,但由于SGA有限,只能從其他區(qū)“搶”過(guò)來(lái)——如縮小Shared Pool,增加Buffer Cache;而有時(shí)又有大塊的PLSQL代碼被解析駐入內(nèi)存中,導(dǎo)致Shared Pool不足,甚至出現(xiàn)4031錯(cuò)誤,又需要擴(kuò)大Shared Pool,這時(shí)可能又需要人為干預(yù),從Buffer Cache中將內(nèi)存奪回來(lái)。

10g 以后有了新特性:自動(dòng)共享內(nèi)存管理(Automatic Shared Memory Management ASMM)。而控制這一特性的,也就僅僅是這一個(gè)參數(shù)SGA_TARGE。設(shè)置這個(gè)參數(shù)后,就不需要為每個(gè)內(nèi)存區(qū)來(lái)指定大小了。SGA_TARGET指定了SGA可以使用的最大內(nèi)存大小,而SGA中各個(gè)內(nèi)存的大小由Oracle自行控制,不需要人為指定。Oracle可以隨時(shí)調(diào)節(jié)各個(gè)區(qū)域的大小,使之達(dá)到系統(tǒng)性能最佳狀態(tài)的個(gè)最合理大小,并且控制他們之和在SGA_TARGET指定的值之內(nèi)。一旦給SGA_TARGET指定值后(默認(rèn)為0,即沒(méi)有啟動(dòng)ASMM),就自動(dòng)啟動(dòng)了ASMM特性。如果不設(shè)置SGA_TARGET,則自動(dòng)共享內(nèi)存管理功能被禁止。

設(shè)置了SGA_TARGET后,以下的SGA內(nèi)存區(qū)就可以由ASMM來(lái)自動(dòng)調(diào)整:

共享池(Shared Pool)

Java池(Java Pool)

大池(Large Pool)

數(shù)據(jù)緩存區(qū)(Buffer Cache)

流池(Streams Pool)

對(duì)于SGA_TARGET的限制,它的大小是不能超過(guò)SGA_MAX_SIZE的大小的。

要注意的是:當(dāng)指定SGA_TARGET小于SGA_MAX_SIZE,實(shí)例重啟后,SGA_MAX_SIZE就自動(dòng)變?yōu)楹蚐GA_TARGET一樣的值了。

SGA_TARGET,它的值可以動(dòng)態(tài)修改(在SGA_MAX_SIZE范圍內(nèi))。在10g之前,如果需要修改SGA的大小(即修改SGA_MAX_SIZE的值)需要重啟實(shí)例才能生效。當(dāng)然,在10g中,修改SGA_MAX_SIZE的值還是需要重啟的。但是有了SGA_TARGET后,可以將SGA_MAX_SIZE設(shè)置偏大,再根據(jù)實(shí)際需要調(diào)整SGA_TARGET的值(我個(gè)人不推薦頻繁修改SGA的大小,SGA_TARGET在實(shí)例啟動(dòng)時(shí)設(shè)置好,以后不要再修改)。

SGA_TARGET帶來(lái)一個(gè)重要的好處就是,能使SGA的利用率達(dá)到最佳,從而節(jié)省內(nèi)存成本。因?yàn)锳SMM啟動(dòng)后,Oracle會(huì)自動(dòng)根據(jù)需要調(diào)整各個(gè)區(qū)域的大小,大大減少了某些區(qū)域內(nèi)存緊張,而某些區(qū)域又有內(nèi)存空閑的矛盾情況出現(xiàn)。這也同時(shí)大大降低了出現(xiàn)4031錯(cuò)誤的幾率。

1.1 Database Buffer Cache

Buffer Cache是SGA區(qū)中專門(mén)用于存放從數(shù)據(jù)文件中讀取的的數(shù)據(jù)塊拷貝的區(qū)域。Oracle進(jìn)程如果發(fā)現(xiàn)需要訪問(wèn)的數(shù)據(jù)塊已經(jīng)在buffer cache中,就直接讀寫(xiě)內(nèi)存中的相應(yīng)區(qū)域,而無(wú)需讀取數(shù)據(jù)文件,從而大大提高性能(內(nèi)存的讀取效率是磁盤(pán)讀取效率的14000倍)。Buffer cache對(duì)于所有oracle進(jìn)程都是共享的,即能被所有oracle進(jìn)程訪問(wèn)。

和Shared Pool一樣,buffer cache被分為多個(gè)集合,這樣能夠大大降低多CPU系統(tǒng)中的爭(zhēng)用問(wèn)題。

1.1.1 Buffer cache的管理

Oracle對(duì)于buffer cache的管理,是通過(guò)兩個(gè)重要的鏈表實(shí)現(xiàn)的:寫(xiě)鏈表和最近最少使用鏈表(the Least Recently Used LRU)。寫(xiě)鏈表所指向的是所有臟數(shù)據(jù)塊緩存(即被進(jìn)程修改過(guò),但還沒(méi)有被回寫(xiě)到數(shù)據(jù)文件中去的數(shù)據(jù)塊,此時(shí)緩沖中的數(shù)據(jù)和數(shù)據(jù)文件中的數(shù)據(jù)不一致)。而LRU鏈表指向的是所有空閑的緩存、pin住的緩存以及還沒(méi)有來(lái)的及移入寫(xiě)鏈表的臟緩存。空閑緩存中沒(méi)有任何有用的數(shù)據(jù),隨時(shí)可以使用。而pin住的緩存是當(dāng)前正在被訪問(wèn)的緩存。LRU鏈表的兩端就分別叫做最近使用端(the Most Recently Used MRU)和最近最少使用端(LRU)。

1)Buffer cache的數(shù)據(jù)塊訪問(wèn)

當(dāng)一個(gè)Oracle進(jìn)程訪問(wèn)一個(gè)緩存時(shí),這個(gè)進(jìn)程會(huì)將這塊緩存移到LRU鏈表中的MRU。而當(dāng)越來(lái)越多的緩沖塊被移到MRU端,那些已經(jīng)過(guò)時(shí)的臟緩沖(即數(shù)據(jù)改動(dòng)已經(jīng)被寫(xiě)入數(shù)據(jù)文件中,此時(shí)緩沖中的數(shù)據(jù)和數(shù)據(jù)文件中的數(shù)據(jù)已經(jīng)一致)則被移到LRU鏈表中LRU端。

當(dāng)一個(gè)Oracle用戶進(jìn)程第一次訪問(wèn)一個(gè)數(shù)據(jù)塊時(shí),它會(huì)先查找buffer cache中是否存在這個(gè)數(shù)據(jù)塊的拷貝。如果發(fā)現(xiàn)這個(gè)數(shù)據(jù)塊已經(jīng)存在于buffer cache(即命中cache hit),它就直接讀從內(nèi)存中取該數(shù)據(jù)塊。如果在buffer cache中沒(méi)有發(fā)現(xiàn)該數(shù)據(jù)塊(即未命中cache miss),它就需要先從數(shù)據(jù)文件中讀取該數(shù)據(jù)塊到buffer cache中,然后才訪問(wèn)該數(shù)據(jù)塊。命中次數(shù)與進(jìn)程讀取次數(shù)之比就是我們一個(gè)衡量數(shù)據(jù)庫(kù)性能的重要指標(biāo):buffer hit ratio(buffer命中率),可以通過(guò)以下語(yǔ)句獲得自實(shí)例啟動(dòng)至今的buffer命中率:

SQL>select (1-(sum(decode(name, 'physical reads',value,0))/(sum(decode(name, 'db block gets',value,0))
         +sum(decode(name,'consistent gets',value,0))))) * 100 "Hit Ratio"  from v$sysstat;

 Hit Ratio

----------

98.3471481

一個(gè)良好性能的系統(tǒng),命中率一般保持在95%左右。

關(guān)于命中率,可以參考我的blog:Oracle 檢查命中率的SQL

http://blog.csdn.net/xujinyang/article/details/6830457

上面提到,如果未命中(missed),則需要先將數(shù)據(jù)塊讀取到緩存中去。這時(shí),oracle進(jìn)程需要從空閑列表種找到一個(gè)適合大小的空閑緩存。如果空閑列表中沒(méi)有適合大小的空閑buffer,它就會(huì)從LRU端開(kāi)始查找LRU鏈表,直到找到一個(gè)可重用的緩存塊或者達(dá)到最大查找塊數(shù)限制。在查找過(guò)程中,如果進(jìn)程找到一個(gè)臟緩存塊,它將這個(gè)緩存塊移到寫(xiě)鏈表中去,然后繼續(xù)查找。當(dāng)它找到一個(gè)空閑塊后,就從磁盤(pán)中讀取數(shù)據(jù)塊到緩存塊中,并將這個(gè)緩存塊移到LRU鏈表的MRU端。

當(dāng)有新的對(duì)象需要請(qǐng)求分配buffer時(shí),會(huì)通過(guò)內(nèi)存管理模塊請(qǐng)求分配空閑的或者可重用的buffer。“free buffer requested”就是產(chǎn)生這種請(qǐng)求的次數(shù);

當(dāng)請(qǐng)求分配buffer時(shí),已經(jīng)沒(méi)有適合大小的空閑buffer時(shí),需要從LRU鏈表上獲取到可重用的buffer。但是,LRU鏈表上的buffer并非都是立即可重用的,還會(huì)存在一些塊正在被讀寫(xiě)或者已經(jīng)被別的用戶所等待。根據(jù)LRU算法,查找可重用的buffer是從鏈表的LRU端開(kāi)始查找的,如果這一段的前面存在這種不能理解被重用的buffer,則需要跳過(guò)去,查找鏈表中的下一個(gè)buffer?!癴ree buffer inspected”就是被跳過(guò)去的buffer的數(shù)目。

如果Oracle用戶進(jìn)程達(dá)到查找塊數(shù)限制后還沒(méi)有找到空閑緩存,它就停止查找LRU鏈表,并且通過(guò)信號(hào)同志DBW0進(jìn)程將臟緩存寫(xiě)入磁盤(pán)去。

2) 全表掃描

當(dāng)發(fā)生全表掃描(Full Table Scan)時(shí),用戶進(jìn)程讀取表的數(shù)據(jù)塊,并將他們放在LRU鏈表的LRU端(和上面不同,不是放在MRU端)。這樣做的目的是為了使全表掃描的數(shù)據(jù)盡快被移出。因?yàn)槿頀呙枰话惆l(fā)生的頻率較低,并且全表掃描的數(shù)據(jù)塊大部分在以后都不會(huì)被經(jīng)常使用到。

而如果你希望全表掃描的數(shù)據(jù)能被cache住,使之在掃描時(shí)放在MRU端,可以通過(guò)在創(chuàng)建或修改表(或簇)時(shí),指定CACHE參數(shù)。

3) Flush Buffer

回顧一下前面一個(gè)用戶進(jìn)程訪問(wèn)一個(gè)數(shù)據(jù)塊的過(guò)程,如果訪問(wèn)的數(shù)據(jù)塊不在buffer cache中,就需要掃描LRU鏈表,當(dāng)達(dá)到掃描塊數(shù)限制后還沒(méi)有找到空閑buffer,就需要通知DBW0將臟緩存回寫(xiě)到磁盤(pán)。如果一個(gè)系統(tǒng)中存在大量的臟緩沖,那么就可能導(dǎo)致用戶進(jìn)程訪問(wèn)數(shù)據(jù)性能下降。

我們可以通過(guò)人工干預(yù)將所有臟緩沖回寫(xiě)到磁盤(pán)去,這就是flush buffer。

在9i,可以用以下語(yǔ)句:

alter system set events = 'immediate trace name flush_cache'; --9i

在10g,可以用以下方式(9i的方式在10g仍然有效):

alter system flush buffer_cache; -- 10g

另外,9i的設(shè)置事件的方式可以是針對(duì)系統(tǒng)全部的,也可以是對(duì)會(huì)話的(即將該會(huì)話造成的臟緩沖回寫(xiě))。

1.1.2 Buffer Cache的重要參數(shù)配置

 1)  Buffer Cache的大小配置

由于Buffer Cache中存放的是從數(shù)據(jù)文件中來(lái)的數(shù)據(jù)塊的拷貝,因此,它的大小的計(jì)算也是以塊的尺寸為基數(shù)的。而數(shù)據(jù)塊的大小是由參數(shù)db_block_size指定的。9i以后,塊的大小默認(rèn)是8K,它的值一般設(shè)置為和操作系統(tǒng)的塊尺寸相同或者它的倍數(shù)。

而參數(shù)db_block_buffers則指定了Buffer Cache中緩存塊數(shù)。因此,buffer cache的大小就等于db_block_buffers * db_block_size。

在9i以后,Oracle引入了一個(gè)新參數(shù):db_cache_size。這個(gè)參數(shù)可以直接指定Buffer Cache的大小,而不需要通過(guò)上面的方式計(jì)算出。它的默認(rèn)值48M,這個(gè)數(shù)對(duì)于一個(gè)系統(tǒng)來(lái)說(shuō)一般是不夠用的。

10G中提供了自動(dòng)內(nèi)存管理,通過(guò)使用sga_target在在多個(gè)組件間自動(dòng)分配內(nèi)存以保證最有效的內(nèi)存使用.如shared pool javapool largepool buffer cache都無(wú)需顯式設(shè)置這些組件的大小,默認(rèn)都是0,當(dāng)某個(gè)組件需要內(nèi)存時(shí),可以通過(guò)內(nèi)部自動(dòng)調(diào)整機(jī)制請(qǐng)求內(nèi)存轉(zhuǎn)移.

注意:db_cache_size和db_block_buffers是不能同時(shí)設(shè)置的,否則實(shí)例啟動(dòng)時(shí)會(huì)報(bào)錯(cuò)。

SQL> alter system set db_block_buffers=16384 scope=spfile;

system altered.

SQL> alter system set db_cache_size=20M scope=memory;

system altered.

SQL> startup force

ORA-00381: cannot use both new and old parameters for buffer cache size specification

9i中,推薦使用db_cache_size來(lái)指定buffer cache的大小。

在OLTP系統(tǒng)中,對(duì)于DB_CACHE_SIZE的設(shè)置,推薦配置是:

DB_CACHE_SIZE = SGA_MAX_SIZE/2~ SGA_MAX_SIZE*2/3

最后,DB_CACHE_SIZE是可以聯(lián)機(jī)修改的,即實(shí)例無(wú)需重啟,除非增大Buffer Cache導(dǎo)致SGA實(shí)際大小大于SGA_MAX_SIZE。

2) 多種塊尺寸系統(tǒng)中的Buffer Cache的配置

從9i開(kāi)始,Oracle支持創(chuàng)建不同塊尺寸的表空間,并且可以為不同塊尺寸的數(shù)據(jù)塊指定不同大小的buffer cache。

9i以后,除了SYSTEM表空間和TEMPORARY表空間必須使用標(biāo)準(zhǔn)塊尺寸外,所有其他表空間都可以最多指定四種不同的塊尺寸。而標(biāo)準(zhǔn)塊尺寸還是由上面的所說(shuō)的參數(shù)db_block_size來(lái)指定。而db_cache_size則是標(biāo)致塊尺寸的buffer cache的大小。

非標(biāo)準(zhǔn)塊尺寸的塊大小可以在創(chuàng)建表空間(CREATE TABLESPACE)是通過(guò)BLOCKSIZE參數(shù)指定。而不同塊尺寸的buffer cache的大小就由相應(yīng)參數(shù)DB_nK_CACHE_SZIE來(lái)指定,其中n可以是2,4,8,16或者32。例如,你創(chuàng)建了一個(gè)塊大小為16K的非標(biāo)準(zhǔn)塊尺寸的表空間,你就可以通過(guò)設(shè)置DB_16K_CACHE_SIZE為來(lái)指定緩存這個(gè)表空間數(shù)據(jù)塊的buffer cache的大小。

任何一個(gè)尺寸的Buffer Cache都是不可以緩存其他尺寸的數(shù)據(jù)塊的。因此,如果你打算使用多種塊尺寸用于你的數(shù)據(jù)庫(kù)的存儲(chǔ),你必須最少設(shè)置DB_CACHE_SIZE和DB_nK_CACHE_SIZE中的一個(gè)參數(shù)(10g后,指定了SGA_TARGET就可以不需要指定Buffer Cache的大?。2⑶?,你需要給你要用到的非標(biāo)準(zhǔn)塊尺寸的數(shù)據(jù)塊指定相應(yīng)的Buffer Cache大小。這些參數(shù)使你可以為系統(tǒng)指定多達(dá)4種不同塊尺寸的Buffer Cache。

另外,注意一點(diǎn),DB_nK_CACHE_SIZE參數(shù)不能設(shè)定標(biāo)準(zhǔn)塊尺寸的緩沖區(qū)大小。舉例來(lái)說(shuō),如果 DB_BLOCK_SIZE設(shè)定為 4K,就不能再設(shè)定 DB_4K_CACHE_SIZE參數(shù)。

3)多緩沖池

可以配置不同的buffer cache,可以達(dá)到不同的cache數(shù)據(jù)的目的。比如,可以設(shè)置一部分buffer cache緩存過(guò)的數(shù)據(jù)在使用后后馬上釋放,使后來(lái)的數(shù)據(jù)可以立即使用緩沖池;還可以設(shè)置數(shù)據(jù)進(jìn)入緩沖池后就被keep住不再釋放。部分?jǐn)?shù)據(jù)庫(kù)對(duì)象(表、簇、索引以及分區(qū))可以控制他們的數(shù)據(jù)緩存的行為,而這些不同的緩存行為就使用不同緩沖池。

保持緩沖池(Keep Buffer Pool)用于緩存那些永久駐入內(nèi)存的數(shù)據(jù)塊。它的大小由參數(shù)DB_KEEP_CACHE_SZIE控制;

回收緩沖池(Recycle Buffer Pool)會(huì)立即清除那些不在使用的數(shù)據(jù)緩存塊。它的大小由參數(shù)DB_RECYLE_CACHE_SIZE指定;

默認(rèn)的標(biāo)準(zhǔn)緩存池,也就是上面所說(shuō)的DB_CACHE_SIZE指定。

這三個(gè)參數(shù)相互之間是獨(dú)立的。并且他們都只適用于標(biāo)準(zhǔn)塊尺寸的數(shù)據(jù)塊。與8i兼容參數(shù)DB_BLOCK_BUFFERS相應(yīng)的,DB_KEEP_CACHE_SIZE對(duì)應(yīng)有BUFFER_POOL_KEEP、DB_RECYLE_CACHE_SIZE對(duì)應(yīng)有BUFFER_POOL_RECYCLE。同樣,這些參數(shù)之間是互斥的,即DB_KEEP_CACHE_SIZE和BUFFER_POOL_KEEP之間只能設(shè)置一個(gè)。

4) 緩沖池建議器

從9i開(kāi)始,Oracle提供了一些自動(dòng)優(yōu)化工具,用于調(diào)整系統(tǒng)配置,提高系統(tǒng)性能。建議器就是其中一種。建議器的作用就是在系統(tǒng)運(yùn)行過(guò)程中,通過(guò)監(jiān)視相關(guān)統(tǒng)計(jì)數(shù)據(jù),給相關(guān)配置在不同情況下的性能效果,提供給DBA做決策,以選取最佳的配置。

9i中,Buffer Cache就有了相應(yīng)的建議器。參數(shù)db_cache_advice用于該建議器的開(kāi)關(guān),默認(rèn)值為FALSE(即關(guān))。當(dāng)設(shè)置它為T(mén)RUE后,在系統(tǒng)運(yùn)行一段時(shí)間后,就可以查詢視圖v$db_cache_advice來(lái)決定如何使之DB_CACHE_SIZE了。關(guān)于這個(gè)建議器和視圖,我們會(huì)在下面的內(nèi)容中介紹。

5) 其他相關(guān)參數(shù)

DB_BLOCK_LRU_LATCHES

LRU鏈表作為一個(gè)內(nèi)存對(duì)象,對(duì)它的訪問(wèn)是需要進(jìn)行鎖(latch)控制的,以防止多個(gè)用戶進(jìn)程同時(shí)使用一個(gè)空閑緩存塊。DB_BLOCK_LRU_LATCHES設(shè)置了LUR latch的數(shù)量范圍。Oracle通過(guò)一系列的內(nèi)部檢測(cè)來(lái)決定是否使用這個(gè)參數(shù)值。如果這個(gè)參數(shù)沒(méi)有設(shè)置,Oracle會(huì)自動(dòng)為它計(jì)算出一個(gè)值。一般來(lái)說(shuō),oracle計(jì)算出來(lái)的值是比較合理,無(wú)需再去修改。

9i以后這個(gè)參數(shù)是隱含參數(shù)。對(duì)于隱含參數(shù),我建議在沒(méi)有得到Oracle支持的情況下不要做修改,否則,如果修改了,Oracle是可以拒絕為你做支持的。

DB_WRITER_PROCESSES

在前面分析Oracle讀取Buffer Cache時(shí),提到一個(gè)Oracle重要的后臺(tái)進(jìn)程DBW0,這個(gè)(或這些)進(jìn)程負(fù)責(zé)將臟緩存塊寫(xiě)回到數(shù)據(jù)文件種去,稱為數(shù)據(jù)庫(kù)書(shū)寫(xiě)器進(jìn)程(Database Writer Process)。DB_WRITER_PROCESSES參數(shù)配置寫(xiě)進(jìn)程的個(gè)數(shù),各個(gè)進(jìn)程以DBWn區(qū)分,其中n>=0,是進(jìn)程序號(hào)。一般情況下,DB_WRITER_PROCESSES = MAX(1, TRUNC(CPU數(shù)/8))。也就是說(shuō),CPU數(shù)小于8時(shí),DB_WRITER_PROCESSES為1,即只有一個(gè)寫(xiě)進(jìn)程DBW0。這對(duì)于一般的系統(tǒng)來(lái)說(shuō)也是足夠用。當(dāng)你的系統(tǒng)的修改數(shù)據(jù)的任務(wù)很重,并且已經(jīng)影響到性能時(shí),可以調(diào)整這個(gè)參數(shù)。這個(gè)參數(shù)不要超過(guò)CPU數(shù),否則多出的進(jìn)程也不會(huì)起作用,另外,它的最大值不能超過(guò)20。

DBWn進(jìn)程除了上面提到的在用戶進(jìn)程讀取buffer cache時(shí)會(huì)被觸發(fā),還能被Checkpoint觸發(fā)(Checkpoint是實(shí)例從redo log中做恢復(fù)的起始點(diǎn))。

1.2 Share Pool

SGA中的共享池由庫(kù)緩存(Library Cache)、字典緩存(Dictionary Cache)、用于并行執(zhí)行消息的緩沖以及控制結(jié)構(gòu)組成。

Shared Pool的大小由參數(shù)SHARED_POOL_SIZE決定。9i中,在32位系統(tǒng)下,這個(gè)參數(shù)的默認(rèn)值是8M,而64位系統(tǒng)下的默認(rèn)值位64M。最大為4G。 10g 以后可以通過(guò)SGA_TARGET 參數(shù)來(lái)自動(dòng)調(diào)整。 

對(duì)于Shared Pool的內(nèi)存管理,是通過(guò)修正過(guò)的LRU算法表來(lái)實(shí)現(xiàn)的。

1.2.1 庫(kù)緩存(Library Cache)

Library Cache中包括共享SQL區(qū)(Shared SQL Areas)、PL/SQL存儲(chǔ)過(guò)程以及控制結(jié)構(gòu)(如鎖、庫(kù)緩存句柄)。

任何用戶都可以訪問(wèn)共享SQL區(qū)(可以通過(guò)v$sqlarea訪問(wèn),隨后會(huì)介紹這個(gè)重要視圖)。因此庫(kù)緩存存在于SGA的共享池中。

1) 共享SQL區(qū)和私有SQL區(qū)

Oracle會(huì)為每一條SQL語(yǔ)句運(yùn)行(每運(yùn)行一條語(yǔ)句Oracle都會(huì)打開(kāi)一個(gè)游標(biāo))提供一個(gè)共享SQL區(qū)(Shared SQL Areas)和私有SQL區(qū)(Private SQL Areas屬于PGA)。當(dāng)發(fā)現(xiàn)兩個(gè)(或多個(gè))用戶都在運(yùn)行同一SQL語(yǔ)句時(shí),Oracle會(huì)重新組織SQL區(qū),使這些用戶能重用共享SQL區(qū)。但他們還會(huì)在私有SQL區(qū)中保存一份這條SQL語(yǔ)句的拷貝。

一個(gè)共享SQL區(qū)中保存了一條語(yǔ)句的解析樹(shù)和查詢計(jì)劃。在多用戶系統(tǒng)中,Oracle通過(guò)為SQL語(yǔ)句使用同一共享SQL區(qū)多次運(yùn)行來(lái)節(jié)省內(nèi)存。

當(dāng)一條新的SQL語(yǔ)句被解析時(shí),Oracle從共享池中分配一塊內(nèi)存來(lái)存儲(chǔ)共享SQL區(qū)。這塊內(nèi)存的大小與這條語(yǔ)句的復(fù)雜性相關(guān)。如果Shared Pool不夠空間分配給共享SQL區(qū),Oracle將釋放從LRU鏈表中查找到最近最少使用的內(nèi)存塊,直到有足夠空間給新的語(yǔ)句的共享SQL區(qū)。如果Oracle釋放的是一個(gè)共享SQL區(qū)的內(nèi)存,那么相應(yīng)的語(yǔ)句在下次執(zhí)行時(shí)需要再次解析并重新分配共享SQL區(qū)。而從解析語(yǔ)句到分配共享SQL區(qū)是一個(gè)比較消耗CPU的工程。這就是為什么我們提倡使用綁定變量的原因了。在沒(méi)有使用綁定變量時(shí),語(yǔ)句中的變量的數(shù)值不同,oracle就視為一條新的語(yǔ)句(9i后可以通過(guò)cursor_sharing來(lái)控制),重復(fù)上面的解析、內(nèi)存分配的動(dòng)作,將大大消耗系統(tǒng)資源,降低系統(tǒng)性能。

2) PL/SQL程序單元

Oracle對(duì)于PL/SQL程序單元(存儲(chǔ)過(guò)程、函數(shù)、包、匿名PL/SQL塊和觸發(fā)器)的處理過(guò)程和對(duì)單個(gè)的SQL語(yǔ)句的處理過(guò)程相似。它會(huì)分配一個(gè)共享區(qū)來(lái)存儲(chǔ)被解析、編譯過(guò)的程序單元。同時(shí)分配一個(gè)私有區(qū)域來(lái)存放運(yùn)行程序單元的會(huì)話所指定的程序單元的參數(shù)值(包括本地變量、全局變量和包變量——這也叫做包的實(shí)例化)和用于執(zhí)行程序所需的內(nèi)存。如果多個(gè)用戶運(yùn)行同一個(gè)程序單元,則他們共享同一個(gè)共享區(qū)域,并且各自保持一份私有區(qū)域,用于用戶會(huì)話中指定的變量值。

而一個(gè)PL/SQL程序單元中的每條單個(gè)SQL語(yǔ)句的處理過(guò)程則和上面描述的SQL語(yǔ)句的處理過(guò)程相同。要注意一點(diǎn),盡管這些語(yǔ)句是從PL/SQL程序單元中來(lái)的,但是Oracle還是會(huì)為這些語(yǔ)句分配一塊共享SQL區(qū),同時(shí)為每個(gè)用戶分配一個(gè)相應(yīng)的私有SQL區(qū)。

1.2.2 字典緩存(Dictionary Cache)

數(shù)據(jù)字典是有關(guān)于數(shù)據(jù)庫(kù)的參考信息、數(shù)據(jù)庫(kù)的結(jié)構(gòu)信息和數(shù)據(jù)庫(kù)中的用戶信息的一組表和視圖的集合,如我們常用到的V$視圖、DBA_視圖都屬于數(shù)據(jù)字典。在SQL語(yǔ)句解析的過(guò)程中,Oracle可以非常迅速的訪問(wèn)(如果需要的話)這些數(shù)據(jù)字典,在SQL Trace中,這種對(duì)數(shù)據(jù)字典的訪問(wèn)就被統(tǒng)計(jì)為回調(diào)(recursive calls)。

因?yàn)镺racle對(duì)數(shù)據(jù)字典訪問(wèn)如此頻繁,因此內(nèi)存中有兩處地方被專門(mén)用于存放數(shù)據(jù)字典。一個(gè)地方就是數(shù)據(jù)字典緩存(Data Dictionary Cache)。數(shù)據(jù)字典緩存也被稱為行緩存(Row Cache),因?yàn)樗且杂涗浶袨閱卧鎯?chǔ)數(shù)據(jù)的,而不像Buffer Cache是以數(shù)據(jù)塊為單元存儲(chǔ)數(shù)據(jù)。內(nèi)存中另外一個(gè)存儲(chǔ)數(shù)據(jù)字典的地方是庫(kù)緩存。所有Oracle的用戶都可以訪問(wèn)這兩個(gè)地方以獲取數(shù)據(jù)字典信息。

1.2.3 共享池的內(nèi)存管理

通常來(lái)說(shuō),共享池是根據(jù)修正過(guò)的LRU算法來(lái)是否其中的對(duì)象(共享SQL區(qū)和數(shù)據(jù)自動(dòng)記錄行)的,否則這些對(duì)象就一直保持在共享池中。如果共享池需要為一個(gè)新對(duì)象分配內(nèi)存,并且共享池中沒(méi)有足夠內(nèi)存時(shí),內(nèi)存中那些不經(jīng)常使用的對(duì)象就被釋放掉。一個(gè)被許多會(huì)話使用過(guò)的共享池對(duì)象,即使最初創(chuàng)建它的進(jìn)程已經(jīng)結(jié)束,只要它是有用的,都會(huì)被修正過(guò)的LRU算法一直保持在共享池中。這樣就使一個(gè)多用戶的Oracle系統(tǒng)對(duì)SQL語(yǔ)句的處理和內(nèi)存消耗最小。

注意,即使一個(gè)共享SQL區(qū)與一個(gè)打開(kāi)的游標(biāo)相關(guān),但如果它長(zhǎng)時(shí)間沒(méi)有被使用,它還是可能會(huì)被從共享池中釋放出來(lái)。而此時(shí)如果打開(kāi)的游標(biāo)還需要運(yùn)行它的相關(guān)語(yǔ)句,Oracle就會(huì)重新解析語(yǔ)句,并分配新的共享SQL區(qū)。

當(dāng)一條SQL語(yǔ)句被提交給Oracle執(zhí)行,Oracle會(huì)自動(dòng)執(zhí)行以下的內(nèi)存分配步驟:

1. Oracle檢查共享池,看是否已經(jīng)存在關(guān)于這條語(yǔ)句的共享SQL區(qū)。如果存在,這個(gè)共享SQL區(qū)就被用于執(zhí)行這條語(yǔ)句。而如果不存在,Oracle就從共享池中分配一塊新的共享SQL區(qū)給這條語(yǔ)句。同時(shí),無(wú)論共享SQL區(qū)存在與否,Oracle都會(huì)為用戶分配一塊私有SQL區(qū)以保存這條語(yǔ)句相關(guān)信息(如變量值)。

2. Oracle為會(huì)話分配一個(gè)私有SQL區(qū)。私有SQL區(qū)的所在與會(huì)話的連接方式相關(guān)。

在以下情況下,Oracle也會(huì)將共享SQL區(qū)從共享池中釋放出來(lái):

1)當(dāng)使用ANALYZE語(yǔ)句更新或刪除表、簇或索引的統(tǒng)計(jì)信息時(shí),所有與被分析對(duì)象相關(guān)的共享SQL區(qū)都被從共享池中釋放掉。當(dāng)下一次被釋放掉的語(yǔ)句被執(zhí)行時(shí),又重新在一個(gè)新的共享SQL區(qū)中根據(jù)被更新過(guò)的統(tǒng)計(jì)信息重新解析。

2) 當(dāng)對(duì)象結(jié)構(gòu)被修改過(guò)后,與該對(duì)象相關(guān)的所有共SQL區(qū)都被標(biāo)識(shí)為無(wú)效(invalid)。在下一次運(yùn)行語(yǔ)句時(shí)再重新解析語(yǔ)句。

3)如果數(shù)據(jù)庫(kù)的全局?jǐn)?shù)據(jù)庫(kù)名(Global Database Name)被修改了,共享池中的所有信息都會(huì)被清空掉。

4)DBA通過(guò)手工方式清空共享池:ALTER SYSTEM FLUSH SHARED_POOL;

Shared Pool能被分成幾個(gè)區(qū)域,分別被不同的latch(latch數(shù)最大為7,可以通過(guò)隱含參數(shù)_kghdsidx_count設(shè)置)保護(hù)。

表x$kghlu可以查看shared pool中的LRU列表。當(dāng)滿足以下條件之一時(shí),shared pool會(huì)分為多個(gè)區(qū),分別有不同的LRU鏈表管理:

1)在10g之前版本,如果shared pool大于128M、CPU數(shù)量大于4;

2)Oracle數(shù)據(jù)庫(kù)版本為10g

這時(shí),在x$kghlu中就會(huì)對(duì)應(yīng)不同記錄。

1.2.4 保留共享池

前面提到,如果Oracle解析一個(gè) PL/SQL程序單元,也需要從共享池中分配內(nèi)存給這些程序單元對(duì)象。由于這些對(duì)象本一般比較大(如包),所以分配的內(nèi)存空間也相對(duì)較大。系統(tǒng)經(jīng)過(guò)長(zhǎng)時(shí)間運(yùn)行后,共享池可能存在大量?jī)?nèi)存碎片,導(dǎo)致無(wú)法滿足對(duì)于大塊內(nèi)存段的分配。

為了使有足夠空間緩存大程序塊,Oracle專門(mén)從共享池內(nèi)置出一塊區(qū)域來(lái)來(lái)分配內(nèi)存保持這些大塊。這個(gè)保留共享池的默認(rèn)大小是共享池的5%。它的大小也可以通過(guò)參數(shù)SHARED_POOL_RESERVED_SIZE來(lái)調(diào)整。保留區(qū)是從共享池中分配,不是直接從SGA中分配的,它是共享池的保留部分,用于存儲(chǔ)大塊段。

Shared Pool中內(nèi)存大于5000字節(jié)的大段就會(huì)被存放在共享池的保留部分。而這個(gè)大小限制是通過(guò)隱含參數(shù)_SHARED_POOL_RESERVED_MIN_ALLOC來(lái)設(shè)定的(如前面所說(shuō),隱含參數(shù)不要去修改它)。除了在實(shí)例啟動(dòng)過(guò)程中,所有小于這個(gè)數(shù)的內(nèi)存段永遠(yuǎn)都不會(huì)放到保留部分中,而大于這個(gè)值的大內(nèi)存段也永遠(yuǎn)不會(huì)存放到非保留區(qū)中,即使共享池的空間不夠用的情況下也是如此。

保留區(qū)的空閑內(nèi)存也不會(huì)被包含在普通共享池的空閑列表中。它會(huì)維護(hù)一個(gè)單獨(dú)的空閑列表。保留池也不會(huì)在它的LRU列表中存放可重建(Recreatable關(guān)于內(nèi)存段的各種狀態(tài)我們?cè)诤竺娴膬?nèi)容中再介紹)段。當(dāng)釋放普通共享池空閑列表上的內(nèi)存時(shí)是不會(huì)清除這些大段的,同樣,在釋放保留池的空閑列表上的大內(nèi)存段時(shí)也不會(huì)清除普通共享池中內(nèi)存。

通過(guò)視圖V$SHARED_POOL_RESERVED可以查到保留池的統(tǒng)計(jì)信息。其中字段REQUEST_MISSES記錄了沒(méi)有立即從空閑列表中得到可用的大內(nèi)存段請(qǐng)求次數(shù)。這個(gè)值要為0。因?yàn)楸A魠^(qū)必須要有足夠個(gè)空閑內(nèi)存來(lái)適應(yīng)那些短期的內(nèi)存請(qǐng)求,而無(wú)需將那些需要長(zhǎng)期cache住的沒(méi)被pin住的可重建的段清除。否則就需要考慮增大SHARED_POOL_RESERVED_SIZE了。

可以通過(guò)觀察視圖V$SHARED_POOL_RESERVED的MAX_USED_SPACE字段來(lái)判斷保留池的大小是否合適。大多數(shù)情況下,你會(huì)觀察到保留池是很少被使用的,也就是說(shuō)5%的保留池空間可能有些浪費(fèi)。但這需要經(jīng)過(guò)長(zhǎng)期觀察來(lái)決定是否需要調(diào)整保留池大小。

保留區(qū)使用shared pool的LRU鏈表來(lái)管理內(nèi)存塊,但是在做掃描時(shí),相互是不受影響的。例如,內(nèi)存管理器掃描shared pool的LRU鏈表,清出空間以分配給一個(gè)小于5000字節(jié)的內(nèi)存請(qǐng)求,是不會(huì)清出保留區(qū)的內(nèi)存塊的,相反亦然。

1.2.5 將重要、常用對(duì)象保持(Keep)在共享池中

根據(jù)LRU算法,一些一段時(shí)間沒(méi)有使用到的內(nèi)存塊會(huì)被情況釋放。這就可能導(dǎo)致一些重要的對(duì)象(如一個(gè)含有大量通用算法函數(shù)的包、被cache的序列)被從內(nèi)存中清除掉。這些對(duì)象可能只是間歇被使用,但是因?yàn)樗麄兊奶幚磉^(guò)程復(fù)雜(不僅包本身重新分配內(nèi)存、解析,還要檢查里面的所有語(yǔ)句),要在內(nèi)存中重建他們的代價(jià)非常大。

我們可以通過(guò)調(diào)用存儲(chǔ)過(guò)程DBMS_SHARED_POOL.KEEP將這些對(duì)象保持在共享池中來(lái)降低這種風(fēng)險(xiǎn)。這個(gè)存儲(chǔ)過(guò)程立即將對(duì)象及其從事對(duì)象載入library cache中,并將他們都標(biāo)記為保持(Keeping)狀態(tài)。對(duì)于這種對(duì)象,我們建議在實(shí)例啟動(dòng)時(shí)就Keep住,以減少內(nèi)存碎片的幾率。

有一種觀點(diǎn)認(rèn)為那些大對(duì)象(如包)是沒(méi)有必要被Keep住的,因?yàn)樗麄儠?huì)被保持在共享池的保留區(qū)(如前所述,這個(gè)區(qū)通常使用率很低),所以一般不可能被清出。這個(gè)觀點(diǎn)是錯(cuò)誤滴!因?yàn)榇蠖鄶?shù)大對(duì)象實(shí)際上是被分為多個(gè)小的內(nèi)存段被載入共享池的,因此根本不會(huì)因?yàn)閷?duì)象的大小而受到特別的保護(hù)。

另外,也不要通過(guò)頻繁調(diào)用某些對(duì)象以防止他們被從共享池中清出。如果共享池大小設(shè)置合理,在系統(tǒng)運(yùn)行的高峰時(shí)期,LRU鏈表會(huì)相對(duì)較短,那些沒(méi)有被pin住的對(duì)象會(huì)很快被清出,除非他們被keep住了。

1.2.6  關(guān)于Shared Pool的重要參數(shù)

  1)  SHARED_POOL_SIZE

它指定了Shared Pool的大小。9i下,在32位系統(tǒng)中,這個(gè)參數(shù)的默認(rèn)值是8M,而64位系統(tǒng)中的默認(rèn)值位64M。

但是,在SGA中還存在一塊叫內(nèi)部SGA消耗(Internal SGA Overhead)的內(nèi)存被放置在共享池中。在9i及之前版本,共享池的統(tǒng)計(jì)大小(通過(guò)v$sgastat視圖統(tǒng)計(jì))為SHARED_POOL_SIZE +內(nèi)部SGA消耗大小。而10g以后,SHARED_POOL_SIZE就已經(jīng)包含了這部分內(nèi)存大小。因此在10g中,共享池的實(shí)際使用大小就是SHARED_POOL_SIZE -內(nèi)部SGA消耗大小,這在配置共享池大小時(shí)需要考慮進(jìn)去,否則,扶過(guò)SHARED_POOL_SIZE設(shè)置過(guò)小,在實(shí)例啟動(dòng)時(shí)就會(huì)報(bào)ORA-00371錯(cuò)誤。

2) SHARED_POOL_RESERVED_SIZE

這個(gè)參數(shù)前面已經(jīng)提到,指定了共享池中緩存大內(nèi)存對(duì)象的保留區(qū)的大小。這里不再贅述。

3)  _SHARED_POOL_RESERVED_MIN_ALLOC

這個(gè)參數(shù)前面也已經(jīng)介紹,設(shè)置了進(jìn)入保留區(qū)的對(duì)象大小的閥值。

1.3 重做日志緩存(Redo Log Buffer)

Redo Log Buffer是SGA中一段保存數(shù)據(jù)庫(kù)修改信息的緩存。這些信息被存儲(chǔ)在重做條目(Redo Entry)中.重做條目中包含了由于INSERT、UPDATE、DELETE、CREATE、ALTER或DROP所做的修改操作而需要對(duì)數(shù)據(jù)庫(kù)重新組織或重做的必須信息。在必要時(shí),重做條目還可以用于數(shù)據(jù)庫(kù)恢復(fù)。

重做條目是Oracle數(shù)據(jù)庫(kù)進(jìn)程從用戶內(nèi)存中拷貝到Redo Log Buffer中去的。重做條目在內(nèi)存中是連續(xù)相連的。后臺(tái)進(jìn)程LGWR負(fù)責(zé)將Redo Log Buffer中的信息寫(xiě)入到磁盤(pán)上活動(dòng)的重做日志文件(Redo Log File)或文件組中去的。

參數(shù)LOG_BUFFER決定了Redo Log Buffer的大小。它的默認(rèn)值是512K(一般這個(gè)大小都是足夠的),最大可以到4G。10g中可通過(guò)參數(shù)自動(dòng)設(shè)置。當(dāng)系統(tǒng)中存在很多的大事務(wù)或者事務(wù)數(shù)量非常多時(shí),可能會(huì)導(dǎo)致日志文件IO增加,降低性能。這時(shí)就可以考慮增加LOG_BUFFER。

但是,Redo Log Buffer的實(shí)際大小并不是LOB_BUFFER的設(shè)定大小。為了保護(hù)Redo Log Buffer,oracle為它增加了保護(hù)頁(yè)(一般為11K):

SQL> select * from v$sgastat where name = 'log_buffer';

POOL         NAME       BYTES

------------ -------------------------- ----------

             log_buffer     7135232

SQL> show parameter log_buffer

NAME                    TYPE        VALUE

------------------------------------ ----------- ----------------

log_buffer                 integer     7024640

SQL>

1.4 大池(large pool)

大池是SGA中的一塊可選內(nèi)存池,根據(jù)需要時(shí)配置。在以下情況下需要配置大池:

1) 用于共享服務(wù)(Shared Server MTS方式中)的會(huì)話內(nèi)存和Oracle分布式事務(wù)處理的Oracle XA接口

2) 使用并行查詢(Parallel Query Option PQO)時(shí)

3)  IO服務(wù)進(jìn)程

4) Oracle備份和恢復(fù)操作(啟用了RMAN時(shí))

通過(guò)從大池中分配會(huì)話內(nèi)存給共享服務(wù)、Oracle XA或并行查詢,oracle可以使用共享池主要來(lái)緩存共享SQL,以防止由于共享SQL緩存收縮導(dǎo)致的性能消耗。此外,為Oracle備份和恢復(fù)操作、IO服務(wù)進(jìn)程和并行查詢分配的內(nèi)存一般都是幾百K,這么大的內(nèi)存段從大池比從共享池更容易分配得到。

參數(shù)LARGE_POOL_SIZE設(shè)置大池的大小。大池是屬于SGA的可變區(qū)(Variable Area)的,它不屬于共享池。對(duì)于大池的訪問(wèn),是受到large memory latch保護(hù)的。大池中只有兩種內(nèi)存段:空閑(free)和可空閑(freeable)內(nèi)存段。它沒(méi)有可重建(recreatable)內(nèi)存段,因此也不用LRU鏈表來(lái)管理(這和其他內(nèi)存區(qū)的管理不同)。大池最大大小為4G。

為了防止大池中產(chǎn)生碎片,隱含參數(shù)_LARGE_POOL_MIN_ALLOC設(shè)置了大池中內(nèi)存段的最小大小,默認(rèn)值是16K(同樣,不建議修改隱含參數(shù))。

此外,large pool是沒(méi)有LRU鏈表的。

1. 5 Java池(Java Pool)

Java池也是SGA中的一塊可選內(nèi)存區(qū),它也屬于SGA中的可變區(qū)。

Java池的內(nèi)存是用于存儲(chǔ)所有會(huì)話中特定Java代碼和JVM中數(shù)據(jù)。Java池的使用方式依賴與Oracle服務(wù)的運(yùn)行模式。

Java池的大小由參數(shù)JAVA_POOL_SIZE設(shè)置。Java Pool最大可到1G。

在Oracle 10g以后,提供了一個(gè)新的建議器——Java池建議器——來(lái)輔助DBA調(diào)整Java池大小。建議器的統(tǒng)計(jì)數(shù)據(jù)可以通過(guò)視圖V$JAVA_POOL_ADVICE來(lái)查詢。如何借助建議器調(diào)整Java池的方法和使用Buffer Cache建議器類(lèi)似,可以參考Buffer Cache中關(guān)于建議器部分。

1.6   流池(Streams Pool)

流池是Oracle 10g中新增加的。是為了增加對(duì)流的支持。

流池也是可選內(nèi)存區(qū),屬于SGA中的可變區(qū)。它的大小可以通過(guò)參數(shù)STREAMS_POOL_SIZE來(lái)指定。如果沒(méi)有被指定,oracle會(huì)在第一次使用流時(shí)自動(dòng)創(chuàng)建。如果設(shè)置了SGA_TARGET參數(shù),Oracle會(huì)從SGA中分配內(nèi)存給流池;如果沒(méi)有指定SGA_TARGET,則從buffer cache中轉(zhuǎn)換一部分內(nèi)存過(guò)來(lái)給流池。轉(zhuǎn)換的大小是共享池大小的10%。

Oracle同樣為流池提供了一個(gè)建議器——流池建議器。建議器的統(tǒng)計(jì)數(shù)據(jù)可以通過(guò)視圖V$STREAMS_POOL_ADVICE查詢。使用方法參看Buffer Cache中關(guān)于優(yōu)化器部分。

二. PGA

PGA(Program Global Area程序全局區(qū))是一塊包含一個(gè)服務(wù)進(jìn)程的數(shù)據(jù)和控制信息的內(nèi)存區(qū)域。它是Oracle在一個(gè)服務(wù)進(jìn)程啟動(dòng)是創(chuàng)建的,是非共享的。一個(gè)Oracle進(jìn)程擁有一個(gè)PGA內(nèi)存區(qū)。一個(gè)PGA也只能被擁有它的那個(gè)服務(wù)進(jìn)程所訪問(wèn),只有這個(gè)進(jìn)程中的Oracle代碼才能讀寫(xiě)它。因此,PGA中的結(jié)構(gòu)是不需要Latch保護(hù)的。

我們可以設(shè)置所有服務(wù)進(jìn)程的PGA內(nèi)存總數(shù)受到實(shí)例分配的總體PGA(Aggregated PGA)限制。

在專有服務(wù)器(Dedicated Server)模式下,Oracle會(huì)為每個(gè)會(huì)話啟動(dòng)一個(gè)Oracle進(jìn)程;而在多線程服務(wù)(Multi-Thread Server MTS)模式下,由多個(gè)會(huì)話共享通一個(gè)Oracle服務(wù)進(jìn)程。

PGA中包含了關(guān)于進(jìn)程使用到的操作系統(tǒng)資源的信息,以及一些關(guān)于進(jìn)程狀態(tài)的信息。而關(guān)于進(jìn)程使用的Oracle共享資源的信息則是在SGA中。這樣做可以使在進(jìn)程以外中止時(shí),能夠及時(shí)釋放和清除這些資源。

 Oracle內(nèi)存和架構(gòu)知識(shí)點(diǎn)有哪些

?Stack Space是用來(lái)存儲(chǔ)用戶會(huì)話變量和數(shù)組的存儲(chǔ)區(qū)域;    

?User Session Data是為用戶會(huì)話使用的附加存儲(chǔ)區(qū)。      

|--Session Information     

|--Sort Area     

|--Cursor Information      

注意Session information(用戶會(huì)話信息)在獨(dú)占服務(wù)器中與在共享服務(wù)器中所處的內(nèi)存區(qū)域是不同的。

2.1  PGA的組成

PGA由兩組區(qū)域組成:固定PGA和可變PGA(或者叫PGA堆,PGA Heap【堆——Heap就是一個(gè)受管理的內(nèi)存區(qū)】)。固定PGA和固定SGA類(lèi)似,它的大小時(shí)固定的,包含了大量原子變量、小的數(shù)據(jù)結(jié)構(gòu)和指向可變PGA的指針。

可變PGA是一個(gè)內(nèi)存堆。它的內(nèi)存段可以通過(guò)視圖X$KSMPP(另外一個(gè)視圖X$KSMSP可以查到可變SGA的內(nèi)存段信息,他們的結(jié)構(gòu)相同)查到。PGA堆包含用于存放X$表的的內(nèi)存(依賴與參數(shù)設(shè)置,包括DB_FILES、CONTROL_FILES)。

總的來(lái)說(shuō),PGA的可變區(qū)中主要分為以下三部分內(nèi)容:

1)私有SQL區(qū);

2)游標(biāo)和SQL區(qū)

3)會(huì)話內(nèi)存

2.1.1 私有SQL區(qū)(Private SQL Area)

私有SQL區(qū)包含了綁定變量值和運(yùn)行時(shí)期內(nèi)存結(jié)構(gòu)信息等數(shù)據(jù)。每一個(gè)運(yùn)行SQL語(yǔ)句的會(huì)話都有一個(gè)塊私有SQL區(qū)。所有提交了相同SQL語(yǔ)句的用戶都有各自的私有SQL區(qū),并且他們共享一個(gè)共享SQL區(qū)。因此,一個(gè)共享SQL區(qū)可能和多個(gè)私有共享區(qū)相關(guān)聯(lián)。

一個(gè)游標(biāo)的私有SQL區(qū)又分為兩個(gè)生命周期不同的區(qū):

 永久區(qū):包含綁定變量信息。當(dāng)游標(biāo)關(guān)閉時(shí)被釋放。

 運(yùn)行區(qū):當(dāng)執(zhí)行結(jié)束時(shí)釋放。

創(chuàng)建運(yùn)行區(qū)是一次執(zhí)行請(qǐng)求的第一步。對(duì)于INSERT、UPDATE和DELETE語(yǔ)句,Oracle在語(yǔ)句運(yùn)行結(jié)束時(shí)釋放運(yùn)行區(qū)。對(duì)于查詢操作,Oracle只有在所有記錄被fetch到或者查詢被取消時(shí)釋放運(yùn)行區(qū)。

2.1.2  游標(biāo)和SQL區(qū)(Cursors and SQL Areas)

一個(gè)Oracle預(yù)編譯程序或OCI程序的應(yīng)用開(kāi)發(fā)人員能夠很明確的打開(kāi)一個(gè)游標(biāo),或者控制一塊特定的私有SQL區(qū),將他們作為程序運(yùn)行的命名資源。另外,oracle隱含的為一些SQL語(yǔ)句產(chǎn)生的遞歸調(diào)用(前面有介紹,讀取數(shù)據(jù)字典信息)也使用共享SQL區(qū)。

私有SQL區(qū)是由用戶進(jìn)程管理的。如何分配和釋放私有SQL區(qū)極大的依賴與你所使用的應(yīng)用工具。而用戶進(jìn)程可以分配的私有SQL區(qū)的數(shù)量是由參數(shù)OPEN_CURSORS控制的,它的默認(rèn)值是50。

在游標(biāo)關(guān)閉前或者語(yǔ)句句柄被釋放前,私有SQL區(qū)將一直存在(但其中的運(yùn)行區(qū)是在語(yǔ)句執(zhí)行結(jié)束時(shí)被釋放,只有永久區(qū)一直存在)下去。應(yīng)用開(kāi)發(fā)人員可以通過(guò)將所有打開(kāi)的不再使用的游標(biāo)都關(guān)閉來(lái)釋放永久區(qū),以減少用戶程序所占用的內(nèi)存。

2.1.3 會(huì)話內(nèi)存(Session Memory)

會(huì)話內(nèi)存是一段用于保存會(huì)話變量(如登錄信息)和其他預(yù)會(huì)話相關(guān)信息的內(nèi)存。對(duì)于共享服務(wù)器模式下,會(huì)話內(nèi)存是共享的,而不是私有的。

對(duì)于復(fù)雜的查詢(如決策支持系統(tǒng)中的查詢),運(yùn)行區(qū)的很大一部分被那些內(nèi)存需求很大的操作分配給SQL工作區(qū)(SQL Work Area)。這些操作包括:

基于排序的操作(ORDER BY、GROUP BY、ROLLUP、窗口函數(shù));

 Hash Join

Bitmap merge

Bitmap create

例如,一個(gè)排序操作使用工作區(qū)(這時(shí)也可叫排序區(qū)Sort Area)來(lái)將一部分?jǐn)?shù)據(jù)行在內(nèi)存排序;而一個(gè)Hash Join操作則使用工作區(qū)(這時(shí)也可以叫做Hash區(qū) Hash Area)來(lái)建立Hash表。如果這兩種操作所處理的數(shù)據(jù)量比工作區(qū)大,那就會(huì)將輸入的數(shù)據(jù)分成一些更小的數(shù)據(jù)片,使一些數(shù)據(jù)片能夠在內(nèi)存中處理,而其他的就在臨時(shí)表空間的磁盤(pán)上稍后處理。盡管工作區(qū)太小時(shí),Bitmap操作不會(huì)將數(shù)據(jù)放到磁盤(pán)上處理,但是他們的復(fù)雜性是和工作區(qū)大小成反比的。因此,總的來(lái)說(shuō),工作區(qū)越大,這些操作就運(yùn)行越快。

工作區(qū)的大小是可以調(diào)整的。一般來(lái)說(shuō),大的工作區(qū)能讓一些特定的操作性能更佳,但也會(huì)消耗更多的內(nèi)存。工作區(qū)的大小足夠適應(yīng)輸入的數(shù)據(jù)和相關(guān)的SQL操作所需的輔助的內(nèi)存就是最優(yōu)的。如果不滿足,因?yàn)樾枰獙⒁徊糠謹(jǐn)?shù)據(jù)放到臨時(shí)表空間磁盤(pán)上處理,操作的響應(yīng)時(shí)間會(huì)增長(zhǎng)。

2.2  PGA內(nèi)存自動(dòng)管理

SQL工作區(qū)可以是自動(dòng)的、全局的管理。DBA只要設(shè)置參數(shù)PGA_AGGREGATE_TARGET給一個(gè)實(shí)例的PGA內(nèi)存指定總的大小。設(shè)置這個(gè)參數(shù)后,Oracle將它作為一個(gè)總的全局限制值,盡量使所有Oracle服務(wù)進(jìn)程的PGA內(nèi)存總數(shù)不超過(guò)這個(gè)值。

在這個(gè)參數(shù)出現(xiàn)之前,DBA要調(diào)整參數(shù)SORT_AREA_SIZE、 HASH_AREA_SIZE,、BITMAP_MERGE_AREA_SIZE和CREATE_BITMAP_AREA_SIZE(關(guān)于這些參數(shù),我們會(huì)在后面介紹),使性能和PGA內(nèi)存消耗最佳。對(duì)這些參數(shù)的調(diào)整是非常麻煩的,因?yàn)榧匆紤]所有相關(guān)的操作,使工作區(qū)適合它們輸入數(shù)據(jù)大小,又要使PGA內(nèi)存不消耗過(guò)大導(dǎo)致系統(tǒng)整體性能下降。

9i以后,通過(guò)設(shè)置了參數(shù)PGA_AGGREGATE_TARGET,使所有會(huì)話的工作區(qū)的大小都是自動(dòng)分配。同時(shí),所有*_AREA_SIZE參數(shù)都會(huì)失效。在任何時(shí)候,實(shí)例中可用于工作區(qū)的PGA內(nèi)存總數(shù)都是基于參數(shù)PGA_AGGREGATE_TARGET的。工作區(qū)內(nèi)存總數(shù)等于參數(shù)PGA_AGGREGATE_TARGET的值減去系統(tǒng)其他組件(如分配給會(huì)話的PGA內(nèi)存)的內(nèi)存消耗。分配給Oracle進(jìn)程的PGA內(nèi)存大小是根據(jù)它們對(duì)內(nèi)存的需求情況來(lái)的。

參數(shù)WORKAREA_SIZE_POLICY決定是否使用PGA_AGGREGATE_TARGET來(lái)管理PGA內(nèi)存。它有兩個(gè)值:AUTO和MANUAL。默認(rèn)是AUTO,即使用PGA_AGGREGATE_TARGET來(lái)管理PGA內(nèi)存。其實(shí),從參數(shù)WORKAREA_SIZE_POLICY的名字上可以看出,Oracle的PGA內(nèi)存自動(dòng)管理只會(huì)調(diào)整工作區(qū)部分,而非工作區(qū)部分(固定PGA區(qū))則不會(huì)受影響。

還有注意一點(diǎn)就是:10g之前,PGA_AGGREGATE_TARGET只在專用服務(wù)模式下生效。而10g以后,PGA內(nèi)存自動(dòng)管理在專有服務(wù)模式(Dedicated Server)和MTS下都有效。另外,9i在OpenVMS系統(tǒng)上還不支持PGA內(nèi)存自動(dòng)管理,但10g支持。

設(shè)置了PGA_AGGREGATE_TARGET以后,每個(gè)進(jìn)程PGA內(nèi)存的大小也是受限制的:

串行操作時(shí),每個(gè)進(jìn)程可用的PGA內(nèi)存為MIN(PGA_AGGREGATE_TARGET * 5%, _pga_max_size/2),其中隱含參數(shù)_pga_max_size的默認(rèn)值是200M,同樣不建議修改它。

并行操作時(shí),并行語(yǔ)句可用的PGA內(nèi)存為PGA_AGGREGATE_TARGET * 30% / DOP(Degree Of Parallelism并行度)。

2.3  專有服務(wù)(Dedicated Server)和共享服務(wù)(Shared Server)

對(duì)PGA內(nèi)存的管理和分配,很大程度上依賴與服務(wù)模式。下面這張表顯示了在不同模式下,PGA內(nèi)存不同部分的分配的異同:

內(nèi)存區(qū)

專有服務(wù)

共享服務(wù)

會(huì)話內(nèi)存

私有的

共享的

永久區(qū)所在區(qū)域

PGA

SGA

SELECT語(yǔ)句的運(yùn)行區(qū)所在區(qū)域

PGA

PGA

DML/DDL語(yǔ)句的運(yùn)行區(qū)所在區(qū)域

PGA

PGA

三. UGA (The User Global Area)

PGA是一段包含一個(gè)Oracle服務(wù)或后臺(tái)進(jìn)程的數(shù)據(jù)和控制信息的內(nèi)存。PGA的大小依賴與系統(tǒng)的配置。在專用服務(wù)(Dedicated Server)模式下,一個(gè)服務(wù)進(jìn)程與一個(gè)用戶進(jìn)程相關(guān),PGA就包括了堆空間和UGA。而UGA(User Global Area用戶全局區(qū))由用戶會(huì)話數(shù)據(jù)、游標(biāo)狀態(tài)和索引區(qū)組成。在共享服務(wù)(MTS)模式下,一個(gè)共享服務(wù)進(jìn)程被多個(gè)用戶進(jìn)程共享,此時(shí)UGA是Shared Pool或Large Pool的一部分(依賴與配置)。

許多DBA都不理解PGA和UGA之間的區(qū)別。其實(shí)這種區(qū)別可以簡(jiǎn)單的理解為進(jìn)程和會(huì)話直接的區(qū)別。在專用服務(wù)模式下,進(jìn)程和會(huì)話是一對(duì)一的;而在MTS模式下,進(jìn)程和會(huì)話是一對(duì)多的關(guān)系。PGA是服務(wù)于進(jìn)程的,它包含的是進(jìn)程的信息;而UGA是服務(wù)于會(huì)話的,它包含的是會(huì)話的信息。因此,MTS模式下,PGA和UGA之間的關(guān)系也是一對(duì)多的。

UGA中包含了一個(gè)會(huì)話的信息,包括:

1)打開(kāi)游標(biāo)的永久區(qū)和運(yùn)行區(qū);

2)包的狀態(tài)信息,特別是包的變量;

3)Java會(huì)話的信息;

4)激活的角色;

5)激活的跟蹤事件(ALTER SESSION SET EVENT …);

6)起作用的NLS參數(shù)(SELECT * FROM NLS_SESSION_PARAMETERS;);

7)所有打開(kāi)的db link;

8)會(huì)話對(duì)于信任的Oracle的托管訪問(wèn)標(biāo)記(mandatory access control (MAC)

和PGA一樣,UGA也由兩組區(qū)組成,固定UGA和可變UGA(或者說(shuō)UGA堆)。固定UGA包含了大概70個(gè)原子變量、小的數(shù)據(jù)結(jié)構(gòu)以及指向UGA堆的指針。

UGA heap中的段可以通過(guò)表X$KSMUP查到(它的結(jié)構(gòu)和X$KSMSP相同)。UGA堆包含了存儲(chǔ)一些固定表(X$表)的永久內(nèi)存(依賴與特定參數(shù)的設(shè)置,如OPEN_CURSORS,OPEN_LINKS和MAX_ENABLED_ROLES)。除此以外,大部分的UGA用于私有SQL區(qū)。UGA內(nèi)存的所在依賴于會(huì)話的設(shè)置。在專用服務(wù)模式下,會(huì)話和進(jìn)程是一對(duì)一的關(guān)系,UGA位于PGA中。固定UGA是PGA中的一段內(nèi)存段,而UGA堆是PGA的子堆。在MTS模式下,固定UGA是shared pool中的一段內(nèi)存段,而UGA堆是Large Pool的子堆,如果從large pool分配失敗,則從shared pool中分配。

MTS模式下,可以通過(guò)Profile中的PRIVATE_SGA項(xiàng)(通過(guò)dba_profiles查看)來(lái)控制每個(gè)UGA占用的SGA的總的大小,但是不建議這樣做。

Oracle 9.2以后,有一個(gè)新的隱含參數(shù):_use_realfree_heap。當(dāng)設(shè)置這個(gè)參數(shù)為true時(shí),Oracle會(huì)為CGA、UGA單獨(dú)分配堆,而不從PGA中分配。它的默認(rèn)值為false,而當(dāng)設(shè)置了pga_aggregate_target后,它的值自動(dòng)被改為true。

四. CGA (The Call Global Area)

與其他的全局區(qū)不同,CGA(Call Global Area調(diào)用全局區(qū))的存在是瞬間的。它只存在于一個(gè)調(diào)用過(guò)程中。對(duì)于實(shí)例的一些低層次的調(diào)用需要CGA,包括:

1)解析一條SQL語(yǔ)句;

2)執(zhí)行一條SQL語(yǔ)句;

3)取一條SELECT語(yǔ)句的輸出值。

如果語(yǔ)句產(chǎn)生了遞歸調(diào)用,則需要為每個(gè)遞歸調(diào)用分配一個(gè)CGA。如上所述,遞歸調(diào)用是在語(yǔ)句解析、優(yōu)化器產(chǎn)生語(yǔ)句查詢計(jì)劃、DML操作時(shí)需要查詢或修改數(shù)據(jù)字典信息的調(diào)用。

無(wú)論UGA存在于PGA還是SGA,CGA都是PGA的subheap。因?yàn)闊o(wú)論那種模式,會(huì)話在做調(diào)用時(shí)總需要一個(gè)進(jìn)行進(jìn)行處理。這一點(diǎn)很重要,特別是在MTS模式下時(shí),如果發(fā)現(xiàn)一次調(diào)用很久沒(méi)有響應(yīng),則可能需要增加PGA的大小。

當(dāng)然,調(diào)用并不是只通過(guò)CGA中的數(shù)據(jù)結(jié)構(gòu)來(lái)工作。實(shí)際上,調(diào)用所需要的大部分的重要數(shù)據(jù)結(jié)構(gòu)都來(lái)自于UGA。例如私有SQL取和排序區(qū)都存放在UGA中,因?yàn)檎{(diào)用結(jié)束后,它們是被保留的。CGA中只包含了那些調(diào)用結(jié)束后可以被釋放的數(shù)據(jù)。例如,CGA中包含了直接IO緩存、關(guān)于遞歸調(diào)用的信息、用于表達(dá)式評(píng)估(產(chǎn)生查詢計(jì)劃時(shí))的的堆空間和其他一些臨時(shí)數(shù)據(jù)。

Java調(diào)用內(nèi)存也分配在CGA中。它被分為三部分空間:堆空間、新空間和老空間。在調(diào)用期間(調(diào)用長(zhǎng)短依賴于使用期長(zhǎng)短和大小),在新空間和老空間中的內(nèi)存段不再使用的內(nèi)存段將被垃圾收集器回收。

五.軟件代碼區(qū)(Software Code Area)

軟件代碼區(qū)是一部分用于存放那些正在運(yùn)行和可以被運(yùn)行的代碼(Oracle自身的代碼)的內(nèi)存區(qū)。Oracle代碼一般存儲(chǔ)在一個(gè)不同于用戶程序存儲(chǔ)區(qū)的軟件代碼區(qū),而用戶程序存儲(chǔ)區(qū)是排他的、受保護(hù)的區(qū)域。

軟件區(qū)的大小一般是固定的,只有Oracle軟件升級(jí)或重裝后才會(huì)改變。在不同操作系統(tǒng)下,這部分區(qū)域所要求的大小也不同。

軟件區(qū)是只讀的,可以被安裝成共享的或非共享的。可能的情況下,Oracle代碼是共享的,這樣所有Oracle用戶都可以直接訪問(wèn)這些代碼,而不需要各自保存一份拷貝在自己的內(nèi)存中。這樣可以節(jié)省大量?jī)?nèi)存并提高整體性能。

而用戶程序也可以是共享的或非共享的。一些Oracle工具(如SQL Plus)能被安裝成共享的,但有些不能。如果一臺(tái)機(jī)器運(yùn)行多個(gè)實(shí)例,這些實(shí)例可以使用同一個(gè)Oracle代碼區(qū)。

另外要注意的是:并不是所有操作系統(tǒng)都能將軟件區(qū)安裝成共享的,如Windows。

“Oracle內(nèi)存和架構(gòu)知識(shí)點(diǎn)有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI