




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Oracle內存架構詳解 Oracle的內存配置與oracle性能息息相關。關于內存的配置,是最影響Oracle性能的配置。內存還直接影響到其他兩個重要資源的消耗:CPU和IO. 先看Oracle內存存儲的主要內容是什么:程序代碼(PLSQL、Java);關于已經連接的會話的信息,包括當前所有活動和非活動會話;程序運行時必須的相關信息,例如查詢計劃;Oracle進程之間共享的信息和相互交流的信息,例如鎖;那些被永久存儲在外圍存儲介質上,被cache在內存中的數據(如redo log條目,數據塊)。 每個Oracle數據庫都是由Oracle Instance(實例)與數據庫(數據文件,控制文件、
2、重做日志文件)組成,其中所謂實例就是用戶同數據庫交互的媒介,用戶通過于一個實例相連來操作數據庫。而實例又是由統一的內存結構(SGA,PGA,UGA)和一批內存駐留進程組成。實例在操作系統中用ORACLE_SID來標識,在Oracle中用參數INSTANCE_NAME來標識, 它們兩個的值是相同的。數據庫啟動時,系統首先在服務器內存中分配系統全局區(qū)(SGA), 構成了Oracle的內存結構,然后啟動若干個常駐內存的操作系統進程,即組成了Oracle的 進程結構,內存區(qū)域和后臺進程合稱為一個Oracle實例。一 SGA SGA是一組為系統分配的共享的內存結構,可以包含一個數據庫實例的數據或控制信息
3、。如果多個用戶連接到同一個數據庫實例,在實例的SGA中,數據可以被多個用戶共享。 當數據庫實例啟動時,SGA的內存被自動分配;當數據庫實例關閉時,SGA內存被回收。 SGA是占用內存最大的一個區(qū)域,同時也是影響數據庫性能的重要因素。SGA區(qū)是可讀寫的。所有登錄到實例的用戶都能讀取SGA中的信息,而在oracle做執(zhí)行操作時,服務進程會將修改的信息寫入SGA區(qū)。SGA主要包括了以下的數據結構:數據緩沖(Buffer Cache)重做日志緩沖(Redo Log Buffer)共享池(Shared Pool)Java池(Java Pool)大池(Large Pool)流池(Streams Pool
4、- 10g以后才有)數據字典緩存(Data Dictionary Cache)其他信息(如數據庫和實例的狀態(tài)信息)SQL> show sgaTotal System Global Area 612368384 bytesFixed Size 1250428 bytesVariable Size 192940932 bytesDatabase Buffers 411041792 bytesRedo Buffers 7135232 bytesSGA 中的數據字典緩存 和其他信息 會被實例的后臺進程所訪問,它們在實例啟動后就固定在SGA中了,而且不會改變,所以這部分又稱為固定SGA(Fixed
5、 SGA)。這部分區(qū)域的大小一般小于100K。Shared Pool、Java Pool、Large Pool和Streams Pool這幾塊內存區(qū)的大小是相應系統參數設置而改變的,所以有通稱為可變SGA(Variable SGA)。截圖出自Oracle 11g 的架構圖。 下載地址:通過下面的語句查詢SQL> show parameter sgaNAME TYPE VALUE- - -lock_sga boolean FALSEpre_page_sga boolean FALSEsga_max_size big integer 584Msga_target big integer 58
6、4M先對這幾個參數做一下說明:SQL> select name,value ,ISSYS_MODIFIABLE from v$parameter where name like 'sga%'NAME VALUE ISSYS_MOD- - -sga_max_size 612368384 FALSEsga_target 612368384 IMMEDIATE如果ISSYS_MODIFIABLE 返回的是false,說明該參數無法用alter system語句動態(tài)修改,需要重啟數據庫。所以sga_max_size 是不可以動態(tài)調整的。但是我們可以對sga_target 進行動態(tài)
7、的調整。 SGA_MAX_SIZE:SGA區(qū)包括了各種緩沖區(qū)和內存池,而大部分都可以通過特定的參數來指定他們的大小。但是,作為一個昂貴的資源,一個系統的物理內存大小是有限。盡管對于CPU的內存尋址來說,是無需關系實際的物理內存大小的,但是過多的使用虛擬內存導致page in/out,會大大影響系統的性能,甚至可能會導致系統crash。所以需要有一個參數來控制SGA使用虛擬內存的最大大小,這個參數就是SGA_MAX_SIZE。當實例啟動后,各個內存區(qū)只分配實例所需要的最小大小,在隨后的運行過程中,再根據需要擴展他們的大小,而他們的總和大小受到了SGA_MAX_SIZE的限制。當試圖增加一個內存的
8、大小,并且如果這個值導致所有內存區(qū)大小總和大于SGA_MAX_SIZE時,oracle會提示錯誤,不允許修改。當然,如果在設置參數時,指定區(qū)域為spfile時(包括修改SGA_MAX_SIZE本身),是不會受到這個限制的。這樣就可能出現這樣的情況,在spfile中,SGA各個內存區(qū)設置大小總和大于SGA_MAX_SIZE。這時,oracle會如下處理:當實例再次啟動時,如果發(fā)現SGA各個內存總和大于SGA_MAX_SIZE,它會將SGA_MAX_SIZE的值修改為SGA各個內存區(qū)總和的值。SGA所分配的是虛擬內存,但是,在我們配置SGA時,一定要使整個SGA區(qū)都在物理內存中,否則,會導致SGA
9、頻繁的頁入/頁出,會極大影響系統性能。對于OLTP系統,一般的建議是將SGA_MAX_SIZE 設為物理內存的60%,PGA 設為20%。 但是現在服務器內存是相當大的。 幾百G的內存隨處可見。60%也就是幾百G內存。 顯然這樣也是不合適的。 所以要根據自己系統來設定設定這個值。這個也就所說的DBA的經驗。 這是是需要經驗的積累。 下表的幾個數值供參考。系統內存SGA_MAX_SIZE值1G400-500M2G1G4G2500M8G5G SGA的實際大小可以通過以下公式估算:SGA實際大小 = DB_CACHE_SIZE + DB_KEEP_CACHE_SIZE + DB_RECYCLE_CA
10、CHE_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實例啟動時,會只載入各個內存區(qū)最小的大小。而其他SGA內存只作為虛擬內存分配,只有當進程touch到相應的頁時,才會置換到物理內存中。我們可以通過設置PRE_PAGE_SGA參數,讓實例一啟動
11、后,所有SGA都分配到物理內存。這個參數的默認值為FALSE,即不將全部SGA置入物理內存中。當設置為TRUE時,實例啟動會將全部SGA置入物理內存中。它可以使實例啟動達到它的最大性能狀態(tài),但是,啟動時間也會更長(因為為了使所有SGA都置入物理內存中,oracle進程需要touch所有的SGA頁)。SQL> alter system set pre_page_sga=true scope=spfile;LOCK_SGA為了保證SGA都被鎖定在物理內存中,而不必頁入/頁出,可以通過參數LOCK_SGA來控制。這個參數默認值為FALSE,當指定為TRUE時,可以將全部SGA都鎖定在物理內存中
12、。當然,有些系統不支持內存鎖定,這個參數也就無效了。SGA_TARGETOracle10g中引入的一個非常重要的參數。在10g之前,SGA的各個內存區(qū)的大小都需要通過各自的參數指定,并且都無法超過參數指定大小的值,盡管他們之和可能并沒有達到SGA的最大限制。此外,一旦分配后,各個區(qū)的內存只能給本區(qū)使用,相互之間是不能共享的。拿SGA中兩個最重要的內存區(qū)Buffer Cache和Shared Pool來說,它們兩個對實例的性能影響最大,但是就有這樣的矛盾存在:在內存資源有限的情況下,某些時候數據被cache的需求非常大,為了提高buffer hit,就需要增加Buffer Cache,但由于SG
13、A有限,只能從其他區(qū)“搶”過來如縮小Shared Pool,增加Buffer Cache;而有時又有大塊的PLSQL代碼被解析駐入內存中,導致Shared Pool不足,甚至出現4031錯誤,又需要擴大Shared Pool,這時可能又需要人為干預,從Buffer Cache中將內存奪回來。10g 以后有了新特性:自動共享內存管理(Automatic Shared Memory Management ASMM)。而控制這一特性的,也就僅僅是這一個參數SGA_TARGE。設置這個參數后,就不需要為每個內存區(qū)來指定大小了。SGA_TARGET指定了SGA可以使用的最大內存大小,而SGA中各個內存的
14、大小由Oracle自行控制,不需要人為指定。Oracle可以隨時調節(jié)各個區(qū)域的大小,使之達到系統性能最佳狀態(tài)的個最合理大小,并且控制他們之和在SGA_TARGET指定的值之內。一旦給SGA_TARGET指定值后(默認為0,即沒有啟動ASMM),就自動啟動了ASMM特性。如果不設置SGA_TARGET,則自動共享內存管理功能被禁止。設置了SGA_TARGET后,以下的SGA內存區(qū)就可以由ASMM來自動調整:共享池(Shared Pool)Java池(Java Pool)大池(Large Pool)數據緩存區(qū)(Buffer Cache)流池(Streams Pool)對于SGA_TARGET的限制
15、,它的大小是不能超過SGA_MAX_SIZE的大小的。要注意的是:當指定SGA_TARGET小于SGA_MAX_SIZE,實例重啟后,SGA_MAX_SIZE就自動變?yōu)楹蚐GA_TARGET一樣的值了。SGA_TARGET,它的值可以動態(tài)修改(在SGA_MAX_SIZE范圍內)。在10g之前,如果需要修改SGA的大?。葱薷腟GA_MAX_SIZE的值)需要重啟實例才能生效。當然,在10g中,修改SGA_MAX_SIZE的值還是需要重啟的。但是有了SGA_TARGET后,可以將SGA_MAX_SIZE設置偏大,再根據實際需要調整SGA_TARGET的值(我個人不推薦頻繁修改SGA的大小,SGA
16、_TARGET在實例啟動時設置好,以后不要再修改)。SGA_TARGET帶來一個重要的好處就是,能使SGA的利用率達到最佳,從而節(jié)省內存成本。因為ASMM啟動后,Oracle會自動根據需要調整各個區(qū)域的大小,大大減少了某些區(qū)域內存緊張,而某些區(qū)域又有內存空閑的矛盾情況出現。這也同時大大降低了出現4031錯誤的幾率。1.1 Database Buffer CacheBuffer Cache是SGA區(qū)中專門用于存放從數據文件中讀取的的數據塊拷貝的區(qū)域。Oracle進程如果發(fā)現需要訪問的數據塊已經在buffer cache中,就直接讀寫內存中的相應區(qū)域,而無需讀取數據文件,從而大大提高性能(內存的讀
17、取效率是磁盤讀取效率的14000倍)。Buffer cache對于所有oracle進程都是共享的,即能被所有oracle進程訪問。和Shared Pool一樣,buffer cache被分為多個集合,這樣能夠大大降低多CPU系統中的爭用問題。1.1.1 Buffer cache的管理Oracle對于buffer cache的管理,是通過兩個重要的鏈表實現的:寫鏈表和最近最少使用鏈表(the Least Recently Used LRU)。寫鏈表所指向的是所有臟數據塊緩存(即被進程修改過,但還沒有被回寫到數據文件中去的數據塊,此時緩沖中的數據和數據文件中的數據不一致)。而LRU鏈表指向的是所有
18、空閑的緩存、pin住的緩存以及還沒有來的及移入寫鏈表的臟緩存??臻e緩存中沒有任何有用的數據,隨時可以使用。而pin住的緩存是當前正在被訪問的緩存。LRU鏈表的兩端就分別叫做最近使用端(the Most Recently Used MRU)和最近最少使用端(LRU)。1)Buffer cache的數據塊訪問當一個Oracle進程訪問一個緩存時,這個進程會將這塊緩存移到LRU鏈表中的MRU。而當越來越多的緩沖塊被移到MRU端,那些已經過時的臟緩沖(即數據改動已經被寫入數據文件中,此時緩沖中的數據和數據文件中的數據已經一致)則被移到LRU鏈表中LRU端。當一個Oracle用戶進程第一次訪問一個數據塊
19、時,它會先查找buffer cache中是否存在這個數據塊的拷貝。如果發(fā)現這個數據塊已經存在于buffer cache(即命中cache hit),它就直接讀從內存中取該數據塊。如果在buffer cache中沒有發(fā)現該數據塊(即未命中cache miss),它就需要先從數據文件中讀取該數據塊到buffer cache中,然后才訪問該數據塊。命中次數與進程讀取次數之比就是我們一個衡量數據庫性能的重要指標:buffer hit ratio(buffer命中率),可以通過以下語句獲得自實例啟動至今的buffer命中率:SQL>select (1-(sum(decode(name, '
20、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上面提到,如果未命中(missed),則需要先將數據塊讀取到緩存中去。這時,oracle進程需
21、要從空閑列表種找到一個適合大小的空閑緩存。如果空閑列表中沒有適合大小的空閑buffer,它就會從LRU端開始查找LRU鏈表,直到找到一個可重用的緩存塊或者達到最大查找塊數限制。在查找過程中,如果進程找到一個臟緩存塊,它將這個緩存塊移到寫鏈表中去,然后繼續(xù)查找。當它找到一個空閑塊后,就從磁盤中讀取數據塊到緩存塊中,并將這個緩存塊移到LRU鏈表的MRU端。當有新的對象需要請求分配buffer時,會通過內存管理模塊請求分配空閑的或者可重用的buffer?!癴ree buffer requested”就是產生這種請求的次數;當請求分配buffer時,已經沒有適合大小的空閑buffer時,需要從LRU鏈
22、表上獲取到可重用的buffer。但是,LRU鏈表上的buffer并非都是立即可重用的,還會存在一些塊正在被讀寫或者已經被別的用戶所等待。根據LRU算法,查找可重用的buffer是從鏈表的LRU端開始查找的,如果這一段的前面存在這種不能理解被重用的buffer,則需要跳過去,查找鏈表中的下一個buffer?!癴ree buffer inspected”就是被跳過去的buffer的數目。如果Oracle用戶進程達到查找塊數限制后還沒有找到空閑緩存,它就停止查找LRU鏈表,并且通過信號同志DBW0進程將臟緩存寫入磁盤去。2) 全表掃描當發(fā)生全表掃描(Full Table Scan)時,用戶進程讀取表
23、的數據塊,并將他們放在LRU鏈表的LRU端(和上面不同,不是放在MRU端)。這樣做的目的是為了使全表掃描的數據盡快被移出。因為全表掃描一般發(fā)生的頻率較低,并且全表掃描的數據塊大部分在以后都不會被經常使用到。而如果你希望全表掃描的數據能被cache住,使之在掃描時放在MRU端,可以通過在創(chuàng)建或修改表(或簇)時,指定CACHE參數。3) Flush Buffer回顧一下前面一個用戶進程訪問一個數據塊的過程,如果訪問的數據塊不在buffer cache中,就需要掃描LRU鏈表,當達到掃描塊數限制后還沒有找到空閑buffer,就需要通知DBW0將臟緩存回寫到磁盤。如果一個系統中存在大量的臟緩沖,那么就
24、可能導致用戶進程訪問數據性能下降。我們可以通過人工干預將所有臟緩沖回寫到磁盤去,這就是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的大小配置
25、由于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的大小,而不需要通過上面的方式計算出。它的默認
26、值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
27、.SQL> alter system set db_cache_size=20M scope=memory;system altered.SQL> startup forceORA-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
28、最后,DB_CACHE_SIZE是可以聯機修改的,即實例無需重啟,除非增大Buffer Cache導致SGA實際大小大于SGA_MAX_SIZE。2) 多種塊尺寸系統中的Buffer Cache的配置從9i開始,Oracle支持創(chuàng)建不同塊尺寸的表空間,并且可以為不同塊尺寸的數據塊指定不同大小的buffer cache。9i以后,除了SYSTEM表空間和TEMPORARY表空間必須使用標準塊尺寸外,所有其他表空間都可以最多指定四種不同的塊尺寸。而標準塊尺寸還是由上面的所說的參數db_block_size來指定。而db_cache_size則是標致塊尺寸的buffer cache的大小。非標準塊尺
29、寸的塊大小可以在創(chuàng)建表空間(CREATE TABLESPACE)是通過BLOCKSIZE參數指定。而不同塊尺寸的buffer cache的大小就由相應參數DB_nK_CACHE_SZIE來指定,其中n可以是2,4,8,16或者32。例如,你創(chuàng)建了一個塊大小為16K的非標準塊尺寸的表空間,你就可以通過設置DB_16K_CACHE_SIZE為來指定緩存這個表空間數據塊的buffer cache的大小。任何一個尺寸的Buffer Cache都是不可以緩存其他尺寸的數據塊的。因此,如果你打算使用多種塊尺寸用于你的數據庫的存儲,你必須最少設置DB_CACHE_SIZE和DB_nK_CACHE_SIZE中
30、的一個參數(10g后,指定了SGA_TARGET就可以不需要指定Buffer Cache的大?。?。并且,你需要給你要用到的非標準塊尺寸的數據塊指定相應的Buffer Cache大小。這些參數使你可以為系統指定多達4種不同塊尺寸的Buffer Cache。另外,注意一點,DB_nK_CACHE_SIZE參數不能設定標準塊尺寸的緩沖區(qū)大小。舉例來說,如果 DB_BLOCK_SIZE設定為 4K,就不能再設定 DB_4K_CACHE_SIZE參數。3)多緩沖池可以配置不同的buffer cache,可以達到不同的cache數據的目的。比如,可以設置一部分buffer cache緩存過的數據在使用后后
31、馬上釋放,使后來的數據可以立即使用緩沖池;還可以設置數據進入緩沖池后就被keep住不再釋放。部分數據庫對象(表、簇、索引以及分區(qū))可以控制他們的數據緩存的行為,而這些不同的緩存行為就使用不同緩沖池。保持緩沖池(Keep Buffer Pool)用于緩存那些永久駐入內存的數據塊。它的大小由參數DB_KEEP_CACHE_SZIE控制;回收緩沖池(Recycle Buffer Pool)會立即清除那些不在使用的數據緩存塊。它的大小由參數DB_RECYLE_CACHE_SIZE指定;默認的標準緩存池,也就是上面所說的DB_CACHE_SIZE指定。這三個參數相互之間是獨立的。并且他們都只適用于標準塊
32、尺寸的數據塊。與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提供了一些自動優(yōu)化工具,用于調整系統配置,提高系統性能。建議器就是其中一種。建議器的作用就是在系統運行過程中,通過監(jiān)視相關統計數據,給相關配置在不同情況下的性能效果,提供給DBA做決策,以選取最佳的配置。9i中
33、,Buffer Cache就有了相應的建議器。參數db_cache_advice用于該建議器的開關,默認值為FALSE(即關)。當設置它為TRUE后,在系統運行一段時間后,就可以查詢視圖v$db_cache_advice來決定如何使之DB_CACHE_SIZE了。關于這個建議器和視圖,我們會在下面的內容中介紹。5) 其他相關參數DB_BLOCK_LRU_LATCHESLRU鏈表作為一個內存對象,對它的訪問是需要進行鎖(latch)控制的,以防止多個用戶進程同時使用一個空閑緩存塊。DB_BLOCK_LRU_LATCHES設置了LUR latch的數量范圍。Oracle通過一系列的內部檢測來決定是
34、否使用這個參數值。如果這個參數沒有設置,Oracle會自動為它計算出一個值。一般來說,oracle計算出來的值是比較合理,無需再去修改。9i以后這個參數是隱含參數。對于隱含參數,我建議在沒有得到Oracle支持的情況下不要做修改,否則,如果修改了,Oracle是可以拒絕為你做支持的。 DB_WRITER_PROCESSES在前面分析Oracle讀取Buffer Cache時,提到一個Oracle重要的后臺進程DBW0,這個(或這些)進程負責將臟緩存塊寫回到數據文件種去,稱為數據庫書寫器進程(Database Writer Process)。DB_WRITER_PROCESSES參數配置寫進程的
35、個數,各個進程以DBWn區(qū)分,其中n>=0,是進程序號。一般情況下,DB_WRITER_PROCESSES = MAX(1, TRUNC(CPU數/8)。也就是說,CPU數小于8時,DB_WRITER_PROCESSES為1,即只有一個寫進程DBW0。這對于一般的系統來說也是足夠用。當你的系統的修改數據的任務很重,并且已經影響到性能時,可以調整這個參數。這個參數不要超過CPU數,否則多出的進程也不會起作用,另外,它的最大值不能超過20。DBWn進程除了上面提到的在用戶進程讀取buffer cache時會被觸發(fā),還能被Checkpoint觸發(fā)(Checkpoint是實例從redo log中
36、做恢復的起始點)。1.2 Share PoolSGA中的共享池由庫緩存(Library Cache)、字典緩存(Dictionary Cache)、用于并行執(zhí)行消息的緩沖以及控制結構組成。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區(qū)(Shared SQ
37、L Areas)、PL/SQL存儲過程以及控制結構(如鎖、庫緩存句柄)。任何用戶都可以訪問共享SQL區(qū)(可以通過v$sqlarea訪問,隨后會介紹這個重要視圖)。因此庫緩存存在于SGA的共享池中。1) 共享SQL區(qū)和私有SQL區(qū)Oracle會為每一條SQL語句運行(每運行一條語句Oracle都會打開一個游標)提供一個共享SQL區(qū)(Shared SQL Areas)和私有SQL區(qū)(Private SQL Areas屬于PGA)。當發(fā)現兩個(或多個)用戶都在運行同一SQL語句時,Oracle會重新組織SQL區(qū),使這些用戶能重用共享SQL區(qū)。但他們還會在私有SQL區(qū)中保存一份這條SQL語句的拷貝。一
38、個共享SQL區(qū)中保存了一條語句的解析樹和查詢計劃。在多用戶系統中,Oracle通過為SQL語句使用同一共享SQL區(qū)多次運行來節(jié)省內存。當一條新的SQL語句被解析時,Oracle從共享池中分配一塊內存來存儲共享SQL區(qū)。這塊內存的大小與這條語句的復雜性相關。如果Shared Pool不夠空間分配給共享SQL區(qū),Oracle將釋放從LRU鏈表中查找到最近最少使用的內存塊,直到有足夠空間給新的語句的共享SQL區(qū)。如果Oracle釋放的是一個共享SQL區(qū)的內存,那么相應的語句在下次執(zhí)行時需要再次解析并重新分配共享SQL區(qū)。而從解析語句到分配共享SQL區(qū)是一個比較消耗CPU的工程。這就是為什么我們提倡使
39、用綁定變量的原因了。在沒有使用綁定變量時,語句中的變量的數值不同,oracle就視為一條新的語句(9i后可以通過cursor_sharing來控制),重復上面的解析、內存分配的動作,將大大消耗系統資源,降低系統性能。2) PL/SQL程序單元Oracle對于PL/SQL程序單元(存儲過程、函數、包、匿名PL/SQL塊和觸發(fā)器)的處理過程和對單個的SQL語句的處理過程相似。它會分配一個共享區(qū)來存儲被解析、編譯過的程序單元。同時分配一個私有區(qū)域來存放運行程序單元的會話所指定的程序單元的參數值(包括本地變量、全局變量和包變量這也叫做包的實例化)和用于執(zhí)行程序所需的內存。如果多個用戶運行同一個程序單元
40、,則他們共享同一個共享區(qū)域,并且各自保持一份私有區(qū)域,用于用戶會話中指定的變量值。而一個PL/SQL程序單元中的每條單個SQL語句的處理過程則和上面描述的SQL語句的處理過程相同。要注意一點,盡管這些語句是從PL/SQL程序單元中來的,但是Oracle還是會為這些語句分配一塊共享SQL區(qū),同時為每個用戶分配一個相應的私有SQL區(qū)。1.2.2 字典緩存(Dictionary Cache) 數據字典是有關于數據庫的參考信息、數據庫的結構信息和數據庫中的用戶信息的一組表和視圖的集合,如我們常用到的V$視圖、DBA_視圖都屬于數據字典。在SQL語句解析的過程中,Oracle可以非常迅速的訪問(如果需要
41、的話)這些數據字典,在SQL Trace中,這種對數據字典的訪問就被統計為回調(recursive calls)。因為Oracle對數據字典訪問如此頻繁,因此內存中有兩處地方被專門用于存放數據字典。一個地方就是數據字典緩存(Data Dictionary Cache)。數據字典緩存也被稱為行緩存(Row Cache),因為它是以記錄行為單元存儲數據的,而不像Buffer Cache是以數據塊為單元存儲數據。內存中另外一個存儲數據字典的地方是庫緩存。所有Oracle的用戶都可以訪問這兩個地方以獲取數據字典信息。1.2.3 共享池的內存管理 通常來說,共享池是根據修正過的LRU算法來是否其中的對象
42、(共享SQL區(qū)和數據自動記錄行)的,否則這些對象就一直保持在共享池中。如果共享池需要為一個新對象分配內存,并且共享池中沒有足夠內存時,內存中那些不經常使用的對象就被釋放掉。一個被許多會話使用過的共享池對象,即使最初創(chuàng)建它的進程已經結束,只要它是有用的,都會被修正過的LRU算法一直保持在共享池中。這樣就使一個多用戶的Oracle系統對SQL語句的處理和內存消耗最小。注意,即使一個共享SQL區(qū)與一個打開的游標相關,但如果它長時間沒有被使用,它還是可能會被從共享池中釋放出來。而此時如果打開的游標還需要運行它的相關語句,Oracle就會重新解析語句,并分配新的共享SQL區(qū)。 當一條SQL語句被提交給O
43、racle執(zhí)行,Oracle會自動執(zhí)行以下的內存分配步驟:1 Oracle檢查共享池,看是否已經存在關于這條語句的共享SQL區(qū)。如果存在,這個共享SQL區(qū)就被用于執(zhí)行這條語句。而如果不存在,Oracle就從共享池中分配一塊新的共享SQL區(qū)給這條語句。同時,無論共享SQL區(qū)存在與否,Oracle都會為用戶分配一塊私有SQL區(qū)以保存這條語句相關信息(如變量值)。2 Oracle為會話分配一個私有SQL區(qū)。私有SQL區(qū)的所在與會話的連接方式相關。在以下情況下,Oracle也會將共享SQL區(qū)從共享池中釋放出來:1)當使用ANALYZE語句更新或刪除表、簇或索引的統計信息時,所有與被分析對象相關的共享S
44、QL區(qū)都被從共享池中釋放掉。當下一次被釋放掉的語句被執(zhí)行時,又重新在一個新的共享SQL區(qū)中根據被更新過的統計信息重新解析。2) 當對象結構被修改過后,與該對象相關的所有共SQL區(qū)都被標識為無效(invalid)。在下一次運行語句時再重新解析語句。3)如果數據庫的全局數據庫名(Global Database Name)被修改了,共享池中的所有信息都會被清空掉。4)DBA通過手工方式清空共享池:ALTER SYSTEM FLUSH SHARED_POOL; Shared Pool能被分成幾個區(qū)域,分別被不同的latch(latch數最大為7,可以通過隱含參數_kghdsidx_count設置)保護
45、。表x$kghlu可以查看shared pool中的LRU列表。當滿足以下條件之一時,shared pool會分為多個區(qū),分別有不同的LRU鏈表管理:1)在10g之前版本,如果shared pool大于128M、CPU數量大于4;2)Oracle數據庫版本為10g這時,在x$kghlu中就會對應不同記錄。1.2.4 保留共享池前面提到,如果Oracle解析一個 PL/SQL程序單元,也需要從共享池中分配內存給這些程序單元對象。由于這些對象本一般比較大(如包),所以分配的內存空間也相對較大。系統經過長時間運行后,共享池可能存在大量內存碎片,導致無法滿足對于大塊內存段的分配。為了使有足夠空間緩存大
46、程序塊,Oracle專門從共享池內置出一塊區(qū)域來來分配內存保持這些大塊。這個保留共享池的默認大小是共享池的5%。它的大小也可以通過參數SHARED_POOL_RESERVED_SIZE來調整。保留區(qū)是從共享池中分配,不是直接從SGA中分配的,它是共享池的保留部分,用于存儲大塊段。Shared Pool中內存大于5000字節(jié)的大段就會被存放在共享池的保留部分。而這個大小限制是通過隱含參數_SHARED_POOL_RESERVED_MIN_ALLOC來設定的(如前面所說,隱含參數不要去修改它)。除了在實例啟動過程中,所有小于這個數的內存段永遠都不會放到保留部分中,而大于這個值的大內存段也永遠不會存
47、放到非保留區(qū)中,即使共享池的空間不夠用的情況下也是如此。保留區(qū)的空閑內存也不會被包含在普通共享池的空閑列表中。它會維護一個單獨的空閑列表。保留池也不會在它的LRU列表中存放可重建(Recreatable關于內存段的各種狀態(tài)我們在后面的內容中再介紹)段。當釋放普通共享池空閑列表上的內存時是不會清除這些大段的,同樣,在釋放保留池的空閑列表上的大內存段時也不會清除普通共享池中內存。通過視圖V$SHARED_POOL_RESERVED可以查到保留池的統計信息。其中字段REQUEST_MISSES記錄了沒有立即從空閑列表中得到可用的大內存段請求次數。這個值要為0。因為保留區(qū)必須要有足夠個空閑內存來適應那
48、些短期的內存請求,而無需將那些需要長期cache住的沒被pin住的可重建的段清除。否則就需要考慮增大SHARED_POOL_RESERVED_SIZE了。可以通過觀察視圖V$SHARED_POOL_RESERVED的MAX_USED_SPACE字段來判斷保留池的大小是否合適。大多數情況下,你會觀察到保留池是很少被使用的,也就是說5%的保留池空間可能有些浪費。但這需要經過長期觀察來決定是否需要調整保留池大小。保留區(qū)使用shared pool的LRU鏈表來管理內存塊,但是在做掃描時,相互是不受影響的。例如,內存管理器掃描shared pool的LRU鏈表,清出空間以分配給一個小于5000字節(jié)的內存
49、請求,是不會清出保留區(qū)的內存塊的,相反亦然。1.2.5 將重要、常用對象保持(Keep)在共享池中根據LRU算法,一些一段時間沒有使用到的內存塊會被情況釋放。這就可能導致一些重要的對象(如一個含有大量通用算法函數的包、被cache的序列)被從內存中清除掉。這些對象可能只是間歇被使用,但是因為他們的處理過程復雜(不僅包本身重新分配內存、解析,還要檢查里面的所有語句),要在內存中重建他們的代價非常大。我們可以通過調用存儲過程DBMS_SHARED_POOL.KEEP將這些對象保持在共享池中來降低這種風險。這個存儲過程立即將對象及其從事對象載入library cache中,并將他們都標記為保持(Ke
50、eping)狀態(tài)。對于這種對象,我們建議在實例啟動時就Keep住,以減少內存碎片的幾率。有一種觀點認為那些大對象(如包)是沒有必要被Keep住的,因為他們會被保持在共享池的保留區(qū)(如前所述,這個區(qū)通常使用率很低),所以一般不可能被清出。這個觀點是錯誤滴!因為大多數大對象實際上是被分為多個小的內存段被載入共享池的,因此根本不會因為對象的大小而受到特別的保護。另外,也不要通過頻繁調用某些對象以防止他們被從共享池中清出。如果共享池大小設置合理,在系統運行的高峰時期,LRU鏈表會相對較短,那些沒有被pin住的對象會很快被清出,除非他們被keep住了。1.2.6 關于Shared Pool的重要參數 1
51、) 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消耗大小,這在配置共享池大小時需要考慮進去,否則
52、,扶過SHARED_POOL_SIZE設置過小,在實例啟動時就會報ORA-00371錯誤。2) SHARED_POOL_RESERVED_SIZE這個參數前面已經提到,指定了共享池中緩存大內存對象的保留區(qū)的大小。這里不再贅述。3) _SHARED_POOL_RESERVED_MIN_ALLOC這個參數前面也已經介紹,設置了進入保留區(qū)的對象大小的閥值。1.3 重做日志緩存(Redo Log Buffer)Redo Log Buffer是SGA中一段保存數據庫修改信息的緩存。這些信息被存儲在重做條目(Redo Entry)中.重做條目中包含了由于INSERT、UPDATE、DELETE、CREAT
53、E、ALTER或DROP所做的修改操作而需要對數據庫重新組織或重做的必須信息。在必要時,重做條目還可以用于數據庫恢復。重做條目是Oracle數據庫進程從用戶內存中拷貝到Redo Log Buffer中去的。重做條目在內存中是連續(xù)相連的。后臺進程LGWR負責將Redo Log Buffer中的信息寫入到磁盤上活動的重做日志文件(Redo Log File)或文件組中去的。參數LOG_BUFFER決定了Redo Log Buffer的大小。它的默認值是512K(一般這個大小都是足夠的),最大可以到4G。10g中可通過參數自動設置。當系統中存在很多的大事務或者事務數量非常多時,可能會導致日志文件IO
54、增加,降低性能。這時就可以考慮增加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 7135232SQL> show parameter log_bufferNAME TYPE VALUE- - -log_buffer integer 7024640SQL&
55、gt;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服務進程和并行查詢
56、分配的內存一般都是幾百K,這么大的內存段從大池比從共享池更容易分配得到。參數LARGE_POOL_SIZE設置大池的大小。大池是屬于SGA的可變區(qū)(Variable Area)的,它不屬于共享池。對于大池的訪問,是受到large memory latch保護的。大池中只有兩種內存段:空閑(free)和可空閑(freeable)內存段。它沒有可重建(recreatable)內存段,因此也不用LRU鏈表來管理(這和其他內存區(qū)的管理不同)。大池最大大小為4G。為了防止大池中產生碎片,隱含參數_LARGE_POOL_MIN_ALLOC設置了大池中內存段的最小大小,默認值是16K(同樣,不建議修改隱含參數)。此外,large pool是沒有LRU鏈表的。1. 5 Java池(Ja
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山東電力高等??茖W校《循證醫(yī)學與流行病學》2023-2024學年第一學期期末試卷
- 山東工藝美術學院《企業(yè)級數據庫的配置和管理》2023-2024學年第二學期期末試卷
- 江蘇省泗陽縣重點名校2025年初三9月聯考數學試題含解析
- 三江學院《Oacle數據庫》2023-2024學年第二學期期末試卷
- 寧夏銀川二中2025屆高三下學期期中聯考物理試題(創(chuàng)新班)試題含解析
- 遼寧師范高等??茖W?!杜R床微生物》2023-2024學年第一學期期末試卷
- 江蘇省南京市示范名校2025年高三下學期第一次診斷考試英語試題含解析
- 房地產分銷代理合同二零二五年
- 房地產抵押管理合同書二零二五年
- 二零二五版落水管安裝高空作業(yè)安全協議書
- 2025-2030銅金屬行業(yè)市場深度調研及前景趨勢與投資研究報告
- 兒童支氣管哮喘診斷與防治指南解讀(2025年)課件
- 廣東省2024-2025學年佛山市普通高中教學質量檢測地理試卷(二)高三試卷(佛山二模)
- 錘擊樁打樁作業(yè)安全培訓
- 網絡安全法律法規(guī)與倫理測試卷
- 2025年遼寧省大連市甘井子區(qū)中考一模語文試題(原卷版)
- 律所律師勞動合同范本
- 2024新滬教版英語初一上單詞表
- SF-36生活質量調查表(SF-36-含評分細則)
- 高等數學課件第一章函數與極限
- LY/T 3292-2021自然保護地生態(tài)旅游規(guī)范
評論
0/150
提交評論