中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Oracle內存和架構知識點有哪些

發布時間:2021-12-22 09:52:51 來源:億速云 閱讀:124 作者:iii 欄目:關系型數據庫

本篇內容介紹了“Oracle內存和架構知識點有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

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

先看Oracle內存存儲的主要內容是什么:

程序代碼(PLSQL、Java);

關于已經連接的會話的信息,包括當前所有活動和非活動會話;

程序運行時必須的相關信息,例如查詢計劃;

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

那些被永久存儲在外圍存儲介質上,被cache在內存中的數據(如redo log條目,數據塊)。

每個Oracle數據庫都是由Oracle Instance(實例)與數據庫(數據文件,控制文件、重做日志文件)組成,其中所謂實例就是用戶同數據庫交互的媒介,用戶通過于一個實例相連來操作數據庫。而實例又是由統一的內存結構(SGA,PGA,UGA)和一批內存駐留進程組成。實例在操作系統中用ORACLE_SID來標識,在Oracle中用參數INSTANCE_NAME來標識, 它們兩個的值是相同的。數據庫啟動時,系統首先在服務器內存中分配系統全局區(SGA), 構成了Oracle的內存結構,然后啟動若干個常駐內存的操作系統進程,即組成了Oracle的 進程結構,內存區域和后臺進程合稱為一個Oracle實例。

一. SGA 

SGA是一組為系統分配的共享的內存結構,可以包含一個數據庫實例的數據或控制信息。如果多個用戶連接到同一個數據庫實例,在實例的SGA中,數據可以被多個用戶共享。   當數據庫實例啟動時,SGA的內存被自動分配;當數據庫實例關閉時,SGA內存被回收。  SGA是占用內存最大的一個區域,同時也是影響數據庫性能的重要因素。

SGA區是可讀寫的。所有登錄到實例的用戶都能讀取SGA中的信息,而在oracle做執行操作時,服務進程會將修改的信息寫入SGA區。

SGA主要包括了以下的數據結構:

數據緩沖(Buffer Cache)

重做日志緩沖(Redo Log Buffer)

共享池(Shared Pool)

Java池(Java Pool)

大池(Large Pool)

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

數據字典緩存(Data Dictionary Cache)

其他信息(如數據庫和實例的狀態信息)

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 中的數據字典緩存 和其他信息 會被實例的后臺進程所訪問,它們在實例啟動后就固定在SGA中了,而且不會改變,所以這部分又稱為固定SGA(Fixed SGA)。這部分區域的大小一般小于100K。

Shared Pool、Java Pool、Large Pool和Streams Pool這幾塊內存區的大小是相應系統參數設置而改變的,所以有通稱為可變SGA(Variable SGA)。

通過下面的語句查詢

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

先對這幾個參數做一下說明:

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,說明該參數無法用alter system語句動態修改,需要重啟數據庫。

所以sga_max_size 是不可以動態調整的。但是我們可以對sga_target 進行動態的調整。 

SGA_MAX_SIZE:

SGA區包括了各種緩沖區和內存池,而大部分都可以通過特定的參數來指定他們的大小。但是,作為一個昂貴的資源,一個系統的物理內存大小是有限。盡管對于CPU的內存尋址來說,是無需關系實際的物理內存大小的,但是過多的使用虛擬內存導致page in/out,會大大影響系統的性能,甚至可能會導致系統crash。所以需要有一個參數來控制SGA使用虛擬內存的最大大小,這個參數就是SGA_MAX_SIZE。

當實例啟動后,各個內存區只分配實例所需要的最小大小,在隨后的運行過程中,再根據需要擴展他們的大小,而他們的總和大小受到了SGA_MAX_SIZE的限制。

當試圖增加一個內存的大小,并且如果這個值導致所有內存區大小總和大于SGA_MAX_SIZE時,oracle會提示錯誤,不允許修改。

當然,如果在設置參數時,指定區域為spfile時(包括修改SGA_MAX_SIZE本身),是不會受到這個限制的。這樣就可能出現這樣的情況,在spfile中,SGA各個內存區設置大小總和大于SGA_MAX_SIZE。這時,oracle會如下處理:當實例再次啟動時,如果發現SGA各個內存總和大于SGA_MAX_SIZE,它會將SGA_MAX_SIZE的值修改為SGA各個內存區總和的值。

SGA所分配的是虛擬內存,但是,在我們配置SGA時,一定要使整個SGA區都在物理內存中,否則,會導致SGA頻繁的頁入/頁出,會極大影響系統性能。

對于OLTP系統,一般的建議是將SGA_MAX_SIZE 設為物理內存的60%,PGA 設為20%。 但是現在服務器內存是相當大的。 幾百G的內存隨處可見。60%也就是幾百G內存。 顯然這樣也是不合適的。 所以要根據自己系統來設定設定這個值。這個也就所說的DBA的經驗。 這是是需要經驗的積累。 

下表的幾個數值供參考。

系統內存

SGA_MAX_SIZE值

1G

400-500M

2G

1G

4G

2500M

8G

5G

SGA的實際大小可以通過以下公式估算:

SGA實際大小 = 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中的新內存池) + LOG_BUFFERS+11K(Redo Log Buffer的保護頁) + 1MB + 16M(SGA內部內存消耗,適合于9i及之前版本)

PRE_PAGE_SGA:

oracle實例啟動時,會只載入各個內存區最小的大小。而其他SGA內存只作為虛擬內存分配,只有當進程touch到相應的頁時,才會置換到物理內存中。我們可以通過設置PRE_PAGE_SGA參數,讓實例一啟動后,所有SGA都分配到物理內存。

這個參數的默認值為FALSE,即不將全部SGA置入物理內存中。當設置為TRUE時,實例啟動會將全部SGA置入物理內存中。它可以使實例啟動達到它的最大性能狀態,但是,啟動時間也會更長(因為為了使所有SGA都置入物理內存中,oracle進程需要touch所有的SGA頁)。

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

LOCK_SGA

為了保證SGA都被鎖定在物理內存中,而不必頁入/頁出,可以通過參數LOCK_SGA來控制。這個參數默認值為FALSE,當指定為TRUE時,可以將全部SGA都鎖定在物理內存中。當然,有些系統不支持內存鎖定,這個參數也就無效了。

SGA_TARGET

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

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

設置了SGA_TARGET后,以下的SGA內存區就可以由ASMM來自動調整:

共享池(Shared Pool)

Java池(Java Pool)

大池(Large Pool)

數據緩存區(Buffer Cache)

流池(Streams Pool)

對于SGA_TARGET的限制,它的大小是不能超過SGA_MAX_SIZE的大小的。

要注意的是:當指定SGA_TARGET小于SGA_MAX_SIZE,實例重啟后,SGA_MAX_SIZE就自動變為和SGA_TARGET一樣的值了。

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

SGA_TARGET帶來一個重要的好處就是,能使SGA的利用率達到最佳,從而節省內存成本。因為ASMM啟動后,Oracle會自動根據需要調整各個區域的大小,大大減少了某些區域內存緊張,而某些區域又有內存空閑的矛盾情況出現。這也同時大大降低了出現4031錯誤的幾率。

1.1 Database Buffer Cache

Buffer Cache是SGA區中專門用于存放從數據文件中讀取的的數據塊拷貝的區域。Oracle進程如果發現需要訪問的數據塊已經在buffer cache中,就直接讀寫內存中的相應區域,而無需讀取數據文件,從而大大提高性能(內存的讀取效率是磁盤讀取效率的14000倍)。Buffer cache對于所有oracle進程都是共享的,即能被所有oracle進程訪問。

和Shared Pool一樣,buffer cache被分為多個集合,這樣能夠大大降低多CPU系統中的爭用問題。

1.1.1 Buffer cache的管理

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

1)Buffer cache的數據塊訪問

當一個Oracle進程訪問一個緩存時,這個進程會將這塊緩存移到LRU鏈表中的MRU。而當越來越多的緩沖塊被移到MRU端,那些已經過時的臟緩沖(即數據改動已經被寫入數據文件中,此時緩沖中的數據和數據文件中的數據已經一致)則被移到LRU鏈表中LRU端。

當一個Oracle用戶進程第一次訪問一個數據塊時,它會先查找buffer cache中是否存在這個數據塊的拷貝。如果發現這個數據塊已經存在于buffer cache(即命中cache hit),它就直接讀從內存中取該數據塊。如果在buffer cache中沒有發現該數據塊(即未命中cache miss),它就需要先從數據文件中讀取該數據塊到buffer cache中,然后才訪問該數據塊。命中次數與進程讀取次數之比就是我們一個衡量數據庫性能的重要指標:buffer hit ratio(buffer命中率),可以通過以下語句獲得自實例啟動至今的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

一個良好性能的系統,命中率一般保持在95%左右。

關于命中率,可以參考我的blog:Oracle 檢查命中率的SQL

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

上面提到,如果未命中(missed),則需要先將數據塊讀取到緩存中去。這時,oracle進程需要從空閑列表種找到一個適合大小的空閑緩存。如果空閑列表中沒有適合大小的空閑buffer,它就會從LRU端開始查找LRU鏈表,直到找到一個可重用的緩存塊或者達到最大查找塊數限制。在查找過程中,如果進程找到一個臟緩存塊,它將這個緩存塊移到寫鏈表中去,然后繼續查找。當它找到一個空閑塊后,就從磁盤中讀取數據塊到緩存塊中,并將這個緩存塊移到LRU鏈表的MRU端。

當有新的對象需要請求分配buffer時,會通過內存管理模塊請求分配空閑的或者可重用的buffer。“free buffer requested”就是產生這種請求的次數;

當請求分配buffer時,已經沒有適合大小的空閑buffer時,需要從LRU鏈表上獲取到可重用的buffer。但是,LRU鏈表上的buffer并非都是立即可重用的,還會存在一些塊正在被讀寫或者已經被別的用戶所等待。根據LRU算法,查找可重用的buffer是從鏈表的LRU端開始查找的,如果這一段的前面存在這種不能理解被重用的buffer,則需要跳過去,查找鏈表中的下一個buffer。“free buffer inspected”就是被跳過去的buffer的數目。

如果Oracle用戶進程達到查找塊數限制后還沒有找到空閑緩存,它就停止查找LRU鏈表,并且通過信號同志DBW0進程將臟緩存寫入磁盤去。

2) 全表掃描

當發生全表掃描(Full Table Scan)時,用戶進程讀取表的數據塊,并將他們放在LRU鏈表的LRU端(和上面不同,不是放在MRU端)。這樣做的目的是為了使全表掃描的數據盡快被移出。因為全表掃描一般發生的頻率較低,并且全表掃描的數據塊大部分在以后都不會被經常使用到。

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

3) Flush Buffer

回顧一下前面一個用戶進程訪問一個數據塊的過程,如果訪問的數據塊不在buffer cache中,就需要掃描LRU鏈表,當達到掃描塊數限制后還沒有找到空閑buffer,就需要通知DBW0將臟緩存回寫到磁盤。如果一個系統中存在大量的臟緩沖,那么就可能導致用戶進程訪問數據性能下降。

我們可以通過人工干預將所有臟緩沖回寫到磁盤去,這就是flush buffer。

在9i,可以用以下語句:

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

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

alter system flush buffer_cache; -- 10g

另外,9i的設置事件的方式可以是針對系統全部的,也可以是對會話的(即將該會話造成的臟緩沖回寫)。

1.1.2 Buffer Cache的重要參數配置

 1)  Buffer Cache的大小配置

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

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

在9i以后,Oracle引入了一個新參數:db_cache_size。這個參數可以直接指定Buffer Cache的大小,而不需要通過上面的方式計算出。它的默認值48M,這個數對于一個系統來說一般是不夠用的。

10G中提供了自動內存管理,通過使用sga_target在在多個組件間自動分配內存以保證最有效的內存使用.如shared pool javapool largepool buffer cache都無需顯式設置這些組件的大小,默認都是0,當某個組件需要內存時,可以通過內部自動調整機制請求內存轉移.

注意:db_cache_size和db_block_buffers是不能同時設置的,否則實例啟動時會報錯。

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來指定buffer cache的大小。

在OLTP系統中,對于DB_CACHE_SIZE的設置,推薦配置是:

DB_CACHE_SIZE = SGA_MAX_SIZE/2~ SGA_MAX_SIZE*2/3

最后,DB_CACHE_SIZE是可以聯機修改的,即實例無需重啟,除非增大Buffer Cache導致SGA實際大小大于SGA_MAX_SIZE。

2) 多種塊尺寸系統中的Buffer Cache的配置

從9i開始,Oracle支持創建不同塊尺寸的表空間,并且可以為不同塊尺寸的數據塊指定不同大小的buffer cache。

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

非標準塊尺寸的塊大小可以在創建表空間(CREATE TABLESPACE)是通過BLOCKSIZE參數指定。而不同塊尺寸的buffer cache的大小就由相應參數DB_nK_CACHE_SZIE來指定,其中n可以是2,4,8,16或者32。例如,你創建了一個塊大小為16K的非標準塊尺寸的表空間,你就可以通過設置DB_16K_CACHE_SIZE為來指定緩存這個表空間數據塊的buffer cache的大小。

任何一個尺寸的Buffer Cache都是不可以緩存其他尺寸的數據塊的。因此,如果你打算使用多種塊尺寸用于你的數據庫的存儲,你必須最少設置DB_CACHE_SIZE和DB_nK_CACHE_SIZE中的一個參數(10g后,指定了SGA_TARGET就可以不需要指定Buffer Cache的大小)。并且,你需要給你要用到的非標準塊尺寸的數據塊指定相應的Buffer Cache大小。這些參數使你可以為系統指定多達4種不同塊尺寸的Buffer Cache。

另外,注意一點,DB_nK_CACHE_SIZE參數不能設定標準塊尺寸的緩沖區大小。舉例來說,如果 DB_BLOCK_SIZE設定為 4K,就不能再設定 DB_4K_CACHE_SIZE參數。

3)多緩沖池

可以配置不同的buffer cache,可以達到不同的cache數據的目的。比如,可以設置一部分buffer cache緩存過的數據在使用后后馬上釋放,使后來的數據可以立即使用緩沖池;還可以設置數據進入緩沖池后就被keep住不再釋放。部分數據庫對象(表、簇、索引以及分區)可以控制他們的數據緩存的行為,而這些不同的緩存行為就使用不同緩沖池。

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

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

默認的標準緩存池,也就是上面所說的DB_CACHE_SIZE指定。

這三個參數相互之間是獨立的。并且他們都只適用于標準塊尺寸的數據塊。與8i兼容參數DB_BLOCK_BUFFERS相應的,DB_KEEP_CACHE_SIZE對應有BUFFER_POOL_KEEP、DB_RECYLE_CACHE_SIZE對應有BUFFER_POOL_RECYCLE。同樣,這些參數之間是互斥的,即DB_KEEP_CACHE_SIZE和BUFFER_POOL_KEEP之間只能設置一個。

4) 緩沖池建議器

從9i開始,Oracle提供了一些自動優化工具,用于調整系統配置,提高系統性能。建議器就是其中一種。建議器的作用就是在系統運行過程中,通過監視相關統計數據,給相關配置在不同情況下的性能效果,提供給DBA做決策,以選取最佳的配置。

9i中,Buffer Cache就有了相應的建議器。參數db_cache_advice用于該建議器的開關,默認值為FALSE(即關)。當設置它為TRUE后,在系統運行一段時間后,就可以查詢視圖v$db_cache_advice來決定如何使之DB_CACHE_SIZE了。關于這個建議器和視圖,我們會在下面的內容中介紹。

5) 其他相關參數

DB_BLOCK_LRU_LATCHES

LRU鏈表作為一個內存對象,對它的訪問是需要進行鎖(latch)控制的,以防止多個用戶進程同時使用一個空閑緩存塊。DB_BLOCK_LRU_LATCHES設置了LUR latch的數量范圍。Oracle通過一系列的內部檢測來決定是否使用這個參數值。如果這個參數沒有設置,Oracle會自動為它計算出一個值。一般來說,oracle計算出來的值是比較合理,無需再去修改。

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

DB_WRITER_PROCESSES

在前面分析Oracle讀取Buffer Cache時,提到一個Oracle重要的后臺進程DBW0,這個(或這些)進程負責將臟緩存塊寫回到數據文件種去,稱為數據庫書寫器進程(Database Writer Process)。DB_WRITER_PROCESSES參數配置寫進程的個數,各個進程以DBWn區分,其中n>=0,是進程序號。一般情況下,DB_WRITER_PROCESSES = MAX(1, TRUNC(CPU數/8))。也就是說,CPU數小于8時,DB_WRITER_PROCESSES為1,即只有一個寫進程DBW0。這對于一般的系統來說也是足夠用。當你的系統的修改數據的任務很重,并且已經影響到性能時,可以調整這個參數。這個參數不要超過CPU數,否則多出的進程也不會起作用,另外,它的最大值不能超過20。

DBWn進程除了上面提到的在用戶進程讀取buffer cache時會被觸發,還能被Checkpoint觸發(Checkpoint是實例從redo log中做恢復的起始點)。

1.2 Share Pool

SGA中的共享池由庫緩存(Library Cache)、字典緩存(Dictionary Cache)、用于并行執行消息的緩沖以及控制結構組成。

Shared Pool的大小由參數SHARED_POOL_SIZE決定。9i中,在32位系統下,這個參數的默認值是8M,而64位系統下的默認值位64M。最大為4G。 10g 以后可以通過SGA_TARGET 參數來自動調整。 

對于Shared Pool的內存管理,是通過修正過的LRU算法表來實現的。

1.2.1 庫緩存(Library Cache)

Library Cache中包括共享SQL區(Shared SQL Areas)、PL/SQL存儲過程以及控制結構(如鎖、庫緩存句柄)。

任何用戶都可以訪問共享SQL區(可以通過v$sqlarea訪問,隨后會介紹這個重要視圖)。因此庫緩存存在于SGA的共享池中。

1) 共享SQL區和私有SQL區

Oracle會為每一條SQL語句運行(每運行一條語句Oracle都會打開一個游標)提供一個共享SQL區(Shared SQL Areas)和私有SQL區(Private SQL Areas屬于PGA)。當發現兩個(或多個)用戶都在運行同一SQL語句時,Oracle會重新組織SQL區,使這些用戶能重用共享SQL區。但他們還會在私有SQL區中保存一份這條SQL語句的拷貝。

一個共享SQL區中保存了一條語句的解析樹和查詢計劃。在多用戶系統中,Oracle通過為SQL語句使用同一共享SQL區多次運行來節省內存。

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

2) PL/SQL程序單元

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

而一個PL/SQL程序單元中的每條單個SQL語句的處理過程則和上面描述的SQL語句的處理過程相同。要注意一點,盡管這些語句是從PL/SQL程序單元中來的,但是Oracle還是會為這些語句分配一塊共享SQL區,同時為每個用戶分配一個相應的私有SQL區。

1.2.2 字典緩存(Dictionary Cache)

數據字典是有關于數據庫的參考信息、數據庫的結構信息和數據庫中的用戶信息的一組表和視圖的集合,如我們常用到的V$視圖、DBA_視圖都屬于數據字典。在SQL語句解析的過程中,Oracle可以非常迅速的訪問(如果需要的話)這些數據字典,在SQL Trace中,這種對數據字典的訪問就被統計為回調(recursive calls)。

因為Oracle對數據字典訪問如此頻繁,因此內存中有兩處地方被專門用于存放數據字典。一個地方就是數據字典緩存(Data Dictionary Cache)。數據字典緩存也被稱為行緩存(Row Cache),因為它是以記錄行為單元存儲數據的,而不像Buffer Cache是以數據塊為單元存儲數據。內存中另外一個存儲數據字典的地方是庫緩存。所有Oracle的用戶都可以訪問這兩個地方以獲取數據字典信息。

1.2.3 共享池的內存管理

通常來說,共享池是根據修正過的LRU算法來是否其中的對象(共享SQL區和數據自動記錄行)的,否則這些對象就一直保持在共享池中。如果共享池需要為一個新對象分配內存,并且共享池中沒有足夠內存時,內存中那些不經常使用的對象就被釋放掉。一個被許多會話使用過的共享池對象,即使最初創建它的進程已經結束,只要它是有用的,都會被修正過的LRU算法一直保持在共享池中。這樣就使一個多用戶的Oracle系統對SQL語句的處理和內存消耗最小。

注意,即使一個共享SQL區與一個打開的游標相關,但如果它長時間沒有被使用,它還是可能會被從共享池中釋放出來。而此時如果打開的游標還需要運行它的相關語句,Oracle就會重新解析語句,并分配新的共享SQL區。

當一條SQL語句被提交給Oracle執行,Oracle會自動執行以下的內存分配步驟:

1. Oracle檢查共享池,看是否已經存在關于這條語句的共享SQL區。如果存在,這個共享SQL區就被用于執行這條語句。而如果不存在,Oracle就從共享池中分配一塊新的共享SQL區給這條語句。同時,無論共享SQL區存在與否,Oracle都會為用戶分配一塊私有SQL區以保存這條語句相關信息(如變量值)。

2. Oracle為會話分配一個私有SQL區。私有SQL區的所在與會話的連接方式相關。

在以下情況下,Oracle也會將共享SQL區從共享池中釋放出來:

1)當使用ANALYZE語句更新或刪除表、簇或索引的統計信息時,所有與被分析對象相關的共享SQL區都被從共享池中釋放掉。當下一次被釋放掉的語句被執行時,又重新在一個新的共享SQL區中根據被更新過的統計信息重新解析。

2) 當對象結構被修改過后,與該對象相關的所有共SQL區都被標識為無效(invalid)。在下一次運行語句時再重新解析語句。

3)如果數據庫的全局數據庫名(Global Database Name)被修改了,共享池中的所有信息都會被清空掉。

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

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

表x$kghlu可以查看shared pool中的LRU列表。當滿足以下條件之一時,shared pool會分為多個區,分別有不同的LRU鏈表管理:

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

2)Oracle數據庫版本為10g

這時,在x$kghlu中就會對應不同記錄。

1.2.4 保留共享池

前面提到,如果Oracle解析一個 PL/SQL程序單元,也需要從共享池中分配內存給這些程序單元對象。由于這些對象本一般比較大(如包),所以分配的內存空間也相對較大。系統經過長時間運行后,共享池可能存在大量內存碎片,導致無法滿足對于大塊內存段的分配。

為了使有足夠空間緩存大程序塊,Oracle專門從共享池內置出一塊區域來來分配內存保持這些大塊。這個保留共享池的默認大小是共享池的5%。它的大小也可以通過參數SHARED_POOL_RESERVED_SIZE來調整。保留區是從共享池中分配,不是直接從SGA中分配的,它是共享池的保留部分,用于存儲大塊段。

Shared Pool中內存大于5000字節的大段就會被存放在共享池的保留部分。而這個大小限制是通過隱含參數_SHARED_POOL_RESERVED_MIN_ALLOC來設定的(如前面所說,隱含參數不要去修改它)。除了在實例啟動過程中,所有小于這個數的內存段永遠都不會放到保留部分中,而大于這個值的大內存段也永遠不會存放到非保留區中,即使共享池的空間不夠用的情況下也是如此。

保留區的空閑內存也不會被包含在普通共享池的空閑列表中。它會維護一個單獨的空閑列表。保留池也不會在它的LRU列表中存放可重建(Recreatable關于內存段的各種狀態我們在后面的內容中再介紹)段。當釋放普通共享池空閑列表上的內存時是不會清除這些大段的,同樣,在釋放保留池的空閑列表上的大內存段時也不會清除普通共享池中內存。

通過視圖V$SHARED_POOL_RESERVED可以查到保留池的統計信息。其中字段REQUEST_MISSES記錄了沒有立即從空閑列表中得到可用的大內存段請求次數。這個值要為0。因為保留區必須要有足夠個空閑內存來適應那些短期的內存請求,而無需將那些需要長期cache住的沒被pin住的可重建的段清除。否則就需要考慮增大SHARED_POOL_RESERVED_SIZE了。

可以通過觀察視圖V$SHARED_POOL_RESERVED的MAX_USED_SPACE字段來判斷保留池的大小是否合適。大多數情況下,你會觀察到保留池是很少被使用的,也就是說5%的保留池空間可能有些浪費。但這需要經過長期觀察來決定是否需要調整保留池大小。

保留區使用shared pool的LRU鏈表來管理內存塊,但是在做掃描時,相互是不受影響的。例如,內存管理器掃描shared pool的LRU鏈表,清出空間以分配給一個小于5000字節的內存請求,是不會清出保留區的內存塊的,相反亦然。

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

根據LRU算法,一些一段時間沒有使用到的內存塊會被情況釋放。這就可能導致一些重要的對象(如一個含有大量通用算法函數的包、被cache的序列)被從內存中清除掉。這些對象可能只是間歇被使用,但是因為他們的處理過程復雜(不僅包本身重新分配內存、解析,還要檢查里面的所有語句),要在內存中重建他們的代價非常大。

我們可以通過調用存儲過程DBMS_SHARED_POOL.KEEP將這些對象保持在共享池中來降低這種風險。這個存儲過程立即將對象及其從事對象載入library cache中,并將他們都標記為保持(Keeping)狀態。對于這種對象,我們建議在實例啟動時就Keep住,以減少內存碎片的幾率。

有一種觀點認為那些大對象(如包)是沒有必要被Keep住的,因為他們會被保持在共享池的保留區(如前所述,這個區通常使用率很低),所以一般不可能被清出。這個觀點是錯誤滴!因為大多數大對象實際上是被分為多個小的內存段被載入共享池的,因此根本不會因為對象的大小而受到特別的保護。

另外,也不要通過頻繁調用某些對象以防止他們被從共享池中清出。如果共享池大小設置合理,在系統運行的高峰時期,LRU鏈表會相對較短,那些沒有被pin住的對象會很快被清出,除非他們被keep住了。

1.2.6  關于Shared Pool的重要參數

  1)  SHARED_POOL_SIZE

它指定了Shared Pool的大小。9i下,在32位系統中,這個參數的默認值是8M,而64位系統中的默認值位64M。

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

2) SHARED_POOL_RESERVED_SIZE

這個參數前面已經提到,指定了共享池中緩存大內存對象的保留區的大小。這里不再贅述。

3)  _SHARED_POOL_RESERVED_MIN_ALLOC

這個參數前面也已經介紹,設置了進入保留區的對象大小的閥值。

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

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

重做條目是Oracle數據庫進程從用戶內存中拷貝到Redo Log Buffer中去的。重做條目在內存中是連續相連的。后臺進程LGWR負責將Redo Log Buffer中的信息寫入到磁盤上活動的重做日志文件(Redo Log File)或文件組中去的。

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

但是,Redo Log Buffer的實際大小并不是LOB_BUFFER的設定大小。為了保護Redo Log Buffer,oracle為它增加了保護頁(一般為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中的一塊可選內存池,根據需要時配置。在以下情況下需要配置大池:

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

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

3)  IO服務進程

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

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

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

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

此外,large pool是沒有LRU鏈表的。

1. 5 Java池(Java Pool)

Java池也是SGA中的一塊可選內存區,它也屬于SGA中的可變區。

Java池的內存是用于存儲所有會話中特定Java代碼和JVM中數據。Java池的使用方式依賴與Oracle服務的運行模式。

Java池的大小由參數JAVA_POOL_SIZE設置。Java Pool最大可到1G。

在Oracle 10g以后,提供了一個新的建議器——Java池建議器——來輔助DBA調整Java池大小。建議器的統計數據可以通過視圖V$JAVA_POOL_ADVICE來查詢。如何借助建議器調整Java池的方法和使用Buffer Cache建議器類似,可以參考Buffer Cache中關于建議器部分。

1.6   流池(Streams Pool)

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

流池也是可選內存區,屬于SGA中的可變區。它的大小可以通過參數STREAMS_POOL_SIZE來指定。如果沒有被指定,oracle會在第一次使用流時自動創建。如果設置了SGA_TARGET參數,Oracle會從SGA中分配內存給流池;如果沒有指定SGA_TARGET,則從buffer cache中轉換一部分內存過來給流池。轉換的大小是共享池大小的10%。

Oracle同樣為流池提供了一個建議器——流池建議器。建議器的統計數據可以通過視圖V$STREAMS_POOL_ADVICE查詢。使用方法參看Buffer Cache中關于優化器部分。

二. PGA

PGA(Program Global Area程序全局區)是一塊包含一個服務進程的數據和控制信息的內存區域。它是Oracle在一個服務進程啟動是創建的,是非共享的。一個Oracle進程擁有一個PGA內存區。一個PGA也只能被擁有它的那個服務進程所訪問,只有這個進程中的Oracle代碼才能讀寫它。因此,PGA中的結構是不需要Latch保護的。

我們可以設置所有服務進程的PGA內存總數受到實例分配的總體PGA(Aggregated PGA)限制。

在專有服務器(Dedicated Server)模式下,Oracle會為每個會話啟動一個Oracle進程;而在多線程服務(Multi-Thread Server MTS)模式下,由多個會話共享通一個Oracle服務進程。

PGA中包含了關于進程使用到的操作系統資源的信息,以及一些關于進程狀態的信息。而關于進程使用的Oracle共享資源的信息則是在SGA中。這樣做可以使在進程以外中止時,能夠及時釋放和清除這些資源。

 Oracle內存和架構知識點有哪些

?Stack Space是用來存儲用戶會話變量和數組的存儲區域;    

?User Session Data是為用戶會話使用的附加存儲區。      

|--Session Information     

|--Sort Area     

|--Cursor Information      

注意Session information(用戶會話信息)在獨占服務器中與在共享服務器中所處的內存區域是不同的。

2.1  PGA的組成

PGA由兩組區域組成:固定PGA和可變PGA(或者叫PGA堆,PGA Heap【堆——Heap就是一個受管理的內存區】)。固定PGA和固定SGA類似,它的大小時固定的,包含了大量原子變量、小的數據結構和指向可變PGA的指針。

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

總的來說,PGA的可變區中主要分為以下三部分內容:

1)私有SQL區;

2)游標和SQL區

3)會話內存

2.1.1 私有SQL區(Private SQL Area)

私有SQL區包含了綁定變量值和運行時期內存結構信息等數據。每一個運行SQL語句的會話都有一個塊私有SQL區。所有提交了相同SQL語句的用戶都有各自的私有SQL區,并且他們共享一個共享SQL區。因此,一個共享SQL區可能和多個私有共享區相關聯。

一個游標的私有SQL區又分為兩個生命周期不同的區:

 永久區:包含綁定變量信息。當游標關閉時被釋放。

 運行區:當執行結束時釋放。

創建運行區是一次執行請求的第一步。對于INSERT、UPDATE和DELETE語句,Oracle在語句運行結束時釋放運行區。對于查詢操作,Oracle只有在所有記錄被fetch到或者查詢被取消時釋放運行區。

2.1.2  游標和SQL區(Cursors and SQL Areas)

一個Oracle預編譯程序或OCI程序的應用開發人員能夠很明確的打開一個游標,或者控制一塊特定的私有SQL區,將他們作為程序運行的命名資源。另外,oracle隱含的為一些SQL語句產生的遞歸調用(前面有介紹,讀取數據字典信息)也使用共享SQL區。

私有SQL區是由用戶進程管理的。如何分配和釋放私有SQL區極大的依賴與你所使用的應用工具。而用戶進程可以分配的私有SQL區的數量是由參數OPEN_CURSORS控制的,它的默認值是50。

在游標關閉前或者語句句柄被釋放前,私有SQL區將一直存在(但其中的運行區是在語句執行結束時被釋放,只有永久區一直存在)下去。應用開發人員可以通過將所有打開的不再使用的游標都關閉來釋放永久區,以減少用戶程序所占用的內存。

2.1.3 會話內存(Session Memory)

會話內存是一段用于保存會話變量(如登錄信息)和其他預會話相關信息的內存。對于共享服務器模式下,會話內存是共享的,而不是私有的。

對于復雜的查詢(如決策支持系統中的查詢),運行區的很大一部分被那些內存需求很大的操作分配給SQL工作區(SQL Work Area)。這些操作包括:

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

 Hash Join

Bitmap merge

Bitmap create

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

工作區的大小是可以調整的。一般來說,大的工作區能讓一些特定的操作性能更佳,但也會消耗更多的內存。工作區的大小足夠適應輸入的數據和相關的SQL操作所需的輔助的內存就是最優的。如果不滿足,因為需要將一部分數據放到臨時表空間磁盤上處理,操作的響應時間會增長。

2.2  PGA內存自動管理

SQL工作區可以是自動的、全局的管理。DBA只要設置參數PGA_AGGREGATE_TARGET給一個實例的PGA內存指定總的大小。設置這個參數后,Oracle將它作為一個總的全局限制值,盡量使所有Oracle服務進程的PGA內存總數不超過這個值。

在這個參數出現之前,DBA要調整參數SORT_AREA_SIZE、 HASH_AREA_SIZE,、BITMAP_MERGE_AREA_SIZE和CREATE_BITMAP_AREA_SIZE(關于這些參數,我們會在后面介紹),使性能和PGA內存消耗最佳。對這些參數的調整是非常麻煩的,因為即要考慮所有相關的操作,使工作區適合它們輸入數據大小,又要使PGA內存不消耗過大導致系統整體性能下降。

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

參數WORKAREA_SIZE_POLICY決定是否使用PGA_AGGREGATE_TARGET來管理PGA內存。它有兩個值:AUTO和MANUAL。默認是AUTO,即使用PGA_AGGREGATE_TARGET來管理PGA內存。其實,從參數WORKAREA_SIZE_POLICY的名字上可以看出,Oracle的PGA內存自動管理只會調整工作區部分,而非工作區部分(固定PGA區)則不會受影響。

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

設置了PGA_AGGREGATE_TARGET以后,每個進程PGA內存的大小也是受限制的:

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

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

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

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

內存區

專有服務

共享服務

會話內存

私有的

共享的

永久區所在區域

PGA

SGA

SELECT語句的運行區所在區域

PGA

PGA

DML/DDL語句的運行區所在區域

PGA

PGA

三. UGA (The User Global Area)

PGA是一段包含一個Oracle服務或后臺進程的數據和控制信息的內存。PGA的大小依賴與系統的配置。在專用服務(Dedicated Server)模式下,一個服務進程與一個用戶進程相關,PGA就包括了堆空間和UGA。而UGA(User Global Area用戶全局區)由用戶會話數據、游標狀態和索引區組成。在共享服務(MTS)模式下,一個共享服務進程被多個用戶進程共享,此時UGA是Shared Pool或Large Pool的一部分(依賴與配置)。

許多DBA都不理解PGA和UGA之間的區別。其實這種區別可以簡單的理解為進程和會話直接的區別。在專用服務模式下,進程和會話是一對一的;而在MTS模式下,進程和會話是一對多的關系。PGA是服務于進程的,它包含的是進程的信息;而UGA是服務于會話的,它包含的是會話的信息。因此,MTS模式下,PGA和UGA之間的關系也是一對多的。

UGA中包含了一個會話的信息,包括:

1)打開游標的永久區和運行區;

2)包的狀態信息,特別是包的變量;

3)Java會話的信息;

4)激活的角色;

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

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

7)所有打開的db link;

8)會話對于信任的Oracle的托管訪問標記(mandatory access control (MAC)

和PGA一樣,UGA也由兩組區組成,固定UGA和可變UGA(或者說UGA堆)。固定UGA包含了大概70個原子變量、小的數據結構以及指向UGA堆的指針。

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

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

Oracle 9.2以后,有一個新的隱含參數:_use_realfree_heap。當設置這個參數為true時,Oracle會為CGA、UGA單獨分配堆,而不從PGA中分配。它的默認值為false,而當設置了pga_aggregate_target后,它的值自動被改為true。

四. CGA (The Call Global Area)

與其他的全局區不同,CGA(Call Global Area調用全局區)的存在是瞬間的。它只存在于一個調用過程中。對于實例的一些低層次的調用需要CGA,包括:

1)解析一條SQL語句;

2)執行一條SQL語句;

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

如果語句產生了遞歸調用,則需要為每個遞歸調用分配一個CGA。如上所述,遞歸調用是在語句解析、優化器產生語句查詢計劃、DML操作時需要查詢或修改數據字典信息的調用。

無論UGA存在于PGA還是SGA,CGA都是PGA的subheap。因為無論那種模式,會話在做調用時總需要一個進行進行處理。這一點很重要,特別是在MTS模式下時,如果發現一次調用很久沒有響應,則可能需要增加PGA的大小。

當然,調用并不是只通過CGA中的數據結構來工作。實際上,調用所需要的大部分的重要數據結構都來自于UGA。例如私有SQL取和排序區都存放在UGA中,因為調用結束后,它們是被保留的。CGA中只包含了那些調用結束后可以被釋放的數據。例如,CGA中包含了直接IO緩存、關于遞歸調用的信息、用于表達式評估(產生查詢計劃時)的的堆空間和其他一些臨時數據。

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

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

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

軟件區的大小一般是固定的,只有Oracle軟件升級或重裝后才會改變。在不同操作系統下,這部分區域所要求的大小也不同。

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

而用戶程序也可以是共享的或非共享的。一些Oracle工具(如SQL Plus)能被安裝成共享的,但有些不能。如果一臺機器運行多個實例,這些實例可以使用同一個Oracle代碼區。

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

“Oracle內存和架構知識點有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

游戏| 鄄城县| 通江县| 洛扎县| 清镇市| 信阳市| 闽清县| 牡丹江市| 黎平县| 湖北省| 镇江市| 大兴区| 五家渠市| 确山县| 枣强县| 沾化县| 屏边| 宁安市| 祁东县| 渝北区| 财经| 松桃| 晋城| 郯城县| 安庆市| 永春县| 琼海市| 海南省| 无为县| 灵璧县| 岳普湖县| 城步| 蓬溪县| 合阳县| 岚皋县| 西安市| 合肥市| 鲁甸县| 安义县| 乌什县| 逊克县|