| Oracle 概念(Oracle 10.2) 第八章 內存結構8、內存結構 這一章描述了Oracle實例的內存結構。 本章包含下列主題: u Oracle內存結構介紹 u 系統(tǒng)全局區(qū)(SGA)概述 u 程序全局區(qū)(PGA)概述 u 專用和共享服務器 u 軟件代碼區(qū)域 Oracle內存結構介紹Oracle使用內存保存下列信息: u 程序代碼 u 連接會話的信息,即使是非活動會話 u 程序執(zhí)行時需要的信息(例如,一個獲取行的查詢的當前狀態(tài)) u 在Oracle進程之間共享和通訊的信息(例如,鎖信息) u 在外部存儲中持久保存的緩存數據(例如,數據塊和重做日志條目) Oracle相關基礎內存結構包括: u 系統(tǒng)全局區(qū)(SGA),在所有服務器進程和后臺進程之間共享 u 程序全局區(qū)(PGA),對于每個服務器進程和后臺進程私有的區(qū)域,每個進程都有一個PGA。 圖8-1 描述了這些內存結構的聯(lián)系。 圖8-1 Oracle內存結構 
 軟件代碼區(qū)域是另外一個基本內存區(qū)域。 系統(tǒng)全局區(qū)(SGA)概述系統(tǒng)全局區(qū)(SGA)是包含Oracle數據庫實例的數據和控制信息的一組共享內存結構。如果多個用戶并發(fā)連接同一個實例,那么實例的SGA數據在用戶之間共享。所以,SGA有時候叫做共享全局區(qū)。 SGA和Oracle進程構成了一個Oracle實例。Oracle在你啟動實例時,自動為SGA分配內存,在你關閉實例時,操作系統(tǒng)釋放內存。每個實例都有它自己的SGA。 SGA是可讀寫的。連接到多進程數據庫實例的所有用戶可以讀取實例SGA中的信息,Oracle運行時多個進程寫數據到SGA。 SGA包含下列數據結構: u 數據庫高速緩存(Database buffer cache) u 重做日志緩存(Redo log buffer) u 共享池(Shared pool) u Java池(Java pool) u 大池(Large pool,可選) u 流池(Streams pool) u 數據字典緩存(Data dictionary cache) u 其他信息 SGA包含數據庫和實例的通用信息,后臺進程需要訪問這部分信息;這部分叫做固定(fixed)SGA。這里不保存用戶數據。SGA還包括進程之間通訊的信息,比如鎖信息。 如果系統(tǒng)使用共享服務器架構,那么請求和回應隊列和PGA的一些內容保存在SGA中。 初始化參數:SGA_MAX_SIZESGA由多個內存組件組成,這些內存是池化的,滿足特定類型的內存分配需求。內存組件的例子包括共享池(用來對執(zhí)行的SQL和PL/SQL分配內存)、Java池(Java對象和其他Java執(zhí)行需要的內存)、高速緩存(buffer cache,用來緩存磁盤塊)。所有的SGA組件按照一個固定的單位(顆粒,granules)來分配和釋放空間。Oracle數據庫使用針對每個SGA組件使用內部的顆粒數量來跟蹤SGA內存。 顆粒尺寸由整體SGA大小決定。在大多數平臺,如果總體SGA尺寸小于1GB,顆粒大小為4M,更大的SGA顆粒尺寸是16M。某些平臺會略有不同。例如,在32位的windows平臺上,SGA尺寸大于1G時,顆粒大小為8M。 Oracle可以設置數據庫SGA使用的虛擬內存的大小。它可以按最小內存啟動實例,允許實例通過擴展SGA組件的內存分配來使用更多的內存,直到達到初始化參數SGA_MAX_SIZE的限制為止。如果初始化參數文件或服務器參數文件(SPFILE)定義的SGA_MAX_SIZE小于所有組件分配的內存之和(可以顯式在參數文件中指定或者默認指定),這時候實例可以初始化,而數據庫忽略SGA_MAX_SIZE的設定。 對大部分系統(tǒng)的性能優(yōu)化來說,整個SGA應該都在實際內存中。如果做不到,而SGA的一部分使用的虛擬內存,然后數據庫系統(tǒng)的整體性能可能迅速下降。原因在于SGA的一部分被操作系統(tǒng)換頁(在磁盤上讀寫)。SGA中分配給所有共享區(qū)域的內存數量也對性能有影響。 SGA的尺寸由多個初始化參數指定。下列參數對于SGA尺寸影響很大: 
 自動共享內存管理(Automatic Shared Memory Management)在以前的數據庫版本中,數據庫管理員(DBA)通過設置一系列初始化參數(包括SHARED_POOL,DB_CACHE_SIZE,JAVA_POOL_SIZE和LARGE_POOL_SIZE)來手工指定不同的SGA組件尺寸。Oracle 10g數據庫包含自動共享內存管理特性,它顯著的簡化了SGA內存管理。在Oracle 10g數據庫中,一個數據庫管理員可以使用初始化參數SGA_TARGET參數來指定實例的SGA內存總量,Oracle數據庫可以在多個組件中自動分布內存,確保有效使用內存。 當啟用了自動SGA內存管理,不同的SGA組件的尺寸是動態(tài)變化的,可以適合工作負載的需要而不需要額外的配置。數據庫根據需要自動在多個組件之間分布可用內存,允許系統(tǒng)最大化使用所有可用SGA內存。 考慮在SGA可用內存為1GB時手工配置,使用如下初始化參數分布: SHARED_POOL_SIZE=128M DB_CACHE_SIZE=896M 如果一個應用試圖對共享池分配多于128M的內存,會產生一個錯誤提示可用共享內存已經耗盡了。在數據庫高速緩存中可能還有空閑的內存,但是這些內存不能被共享池使用。你不得不手工重新調整高速緩存(buffer cache)和共享池(shared pool)來解決這個問題。 通過自動SGA管理,你可以簡單的設置初始化參數SGA_TARGET為1G。如果應用需要更多的共享池內存,它可以從高速緩存(buffer cache)中獲得空閑的內存。 設置一個簡單的參數可以大大簡化管理員工作。你只需要指定實例可用的SGA內存總量,不用考慮單獨組件的大小設置。只要系統(tǒng)事實上沒有耗盡內存,就不會產生內存錯誤。 自動SGA管理可以提高負載性能,而不需要額外的資源和手工的調整。使用SGA手工配置,可能因為內存不足,造成編譯的SQL語句從共享池中頻繁老化(即清理出共享池)。這會導致頻繁硬解析,導致性能降低。當自動SGA管理啟用時,一個內部機制會監(jiān)控負載性能,如果它認為提升共享池尺寸可以降低需要的解析數量,就會提升共享池尺寸。 初始化參數SGA_TARGETSGA_TARGET初始化參數影響整個SGA尺寸,包括下列組件的內存: u 固定SGA和其他Oracle數據庫實例需要的內部分配 u 日志緩存(log buffer) u 共享池(shared pool) u Java池(Java pool) u 高速緩存(buffer cache) u 保存池和循環(huán)池緩存(keep and recycle buffer caches,如果指定的話) u 非標準塊尺寸的高速緩存(如果指定的話) u 流池(Streams pool) SGA_TARGET包含SGA的全部內存是有重大意義的,和以前的發(fā)布版本比較,內部和固定SGA加入SGA內存配置參數的總和中。因而SGA_TARGET可以讓你精確控制數據庫分配給共享內存區(qū)域的大小。如果啟動時SGA_TARGET設置值大于SGA_MAX_SIZE,然后后者會根據SGA_TARGET調整。 注意:不能動態(tài)設置和取消SGA_TARGET參數。只有在實例啟動時設置。 自動管理SGA組件當你設置SGA_TARGET值時,Oracle 10g數據庫自動定義大多數通用配置組件的尺寸,包括: u 共享池(SQL和PL/SQL執(zhí)行) u Java池(Java執(zhí)行區(qū)域) u 大池(大的內存分配,如RMAN備份緩存) u 高速緩存(buffer cache) u 流池 你不需要顯式的設置這些組件的大小。默認這些組件的相關參數的值都為0。無論何時一個組件需要內存,另一個組件根據內部自動調整機制傳輸一部分內存給它。內存?zhèn)鬏斒峭耆该鞯?,不需要用戶干預。 Oracle數據庫實例監(jiān)控每個自動改變尺寸的組件的性能。實例使用內部視圖和統(tǒng)計信息來確定在這些組件之間如何分布內存最優(yōu)。當負載改變時,內存會重新分布來確保最優(yōu)性能。為了計算最優(yōu)的內存分布,數據庫使用一種機制同時考慮長期和短期趨勢。 手工管理SGA組件有些SGA組件的尺寸是不能自動調整。如果應用需要的話,管理員需要顯式的指定這些組件的大小。這些組件是: u 緩存保持池和循環(huán)池(DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE控制) u 非標準塊大小的額外高速緩存(參數DB_nK_CACHE_SIZE,n={2,4,8,16,32}) 這些組件的大小由管理員定義對應的參數值來確定。這些值當然可以在任何時候通過企業(yè)管理器或者ALTER SYSTEM語句在命令行改變。 手工指定大小的組件消耗的內存減少了自動調整的可用內存量。例如,在下面的配置中: SGA_TARGET = 256M DB_8K_CACHE_SIZE = 32M 這個實例只有224M(256-32)可以用來在自動調整組件之間分布內存。 自動調整值的持久性 如果你使用服務器參數文件(SPFILE),即使關閉重啟,Oracle數據庫也會記住自動調整組件的大小。因此,系統(tǒng)不需要在實例重啟時再次學習負載的規(guī)格參數。它可以從上一個實例的信息開始,并可以從上次關閉的中斷繼續(xù)評估負載。 跟蹤組件大小和增加顆粒數據庫管理員使用ALTER SYSTEM語句來修改相關組件的初始化參數值來擴張SGA一個組件的使用。Oracle數據庫將新值轉換為最近的16MB的整數倍,進而增加和減少顆粒來達到目的值。數據庫必須有足夠的空閑顆粒才滿足需求。只要SGA內存的當前值小于SGA_MAX_SIZE,數據庫就可以分配更多的顆粒,直到SGA尺寸達到SGA_MAX_SIZE為止。 SGA中每個組件當前使用的顆粒值可以在視圖V$SGAINFO中顯示。每個組件大小和上次重定義組件大小的操作時間和類型可以在V$SGA_DYNAMIC_COMPONENTS視圖中看到。數據庫保存最近400次修改SGA組件的操作。你可以在視圖V$SGA_RESIZE_OPS中看到這些緩存的循環(huán)。 注意:如果你指定一個組件尺寸不是顆粒大小的倍數,然后Oracle增加指定大小到最近的倍數。例如,如果顆粒大小是4MB,你指定了DB_CACHE_SIZE為10MB,你最終被分配的是12MB。 數據庫高速緩存(buffer cache)數據庫高速緩存是SGA的一部分,保存從數據文件讀取的數據塊的拷貝。所有并發(fā)訪問實例的用戶共享訪問數據庫高速緩存。 數據庫高速緩存和共享SQL緩存邏輯上分為多個集合。組織為多個集合降低了多處理器環(huán)境的爭用。 數據庫高速緩存的組織 高速緩存分為兩個列表:寫列表和最近最少使用列表(LRU)。寫列表保存臟緩存,這部分包含已經修改了但是還沒有寫入磁盤的數據。LRU列表保存空閑緩存、釘住緩存、還沒有移入寫列表的臟緩存??臻e緩存不包含任何有用數據,是可用的。釘住緩存是當前訪問的緩存。 當Oracle進程訪問一個緩存,進程會將緩存移動到LRU列表的最近經常使用端。隨著更多的緩存移動到LRU列表的最近經常使用端,臟塊順著LRU列表的最近最少使用端老化。 當Oracle用戶進程第一次請求一個特定的數據,它先在數據庫高速緩存中查找數據。如果進程發(fā)現數據已經在緩存中(cache hit),它可以直接從內存中讀取數據。如果進程不能在緩存中找到數據(cache miss),它必須從磁盤上的數據文件拷貝數據塊到緩存中,然后才能訪問數據。通過Cache hit訪問數據比Cache miss訪問要快的多。 在讀取數據塊到緩存之前,進程必須首先找到空閑的緩存。進程搜索LRU列表,從最近經常使用端開始搜索。進程或者找到空閑的緩存,或者達到緩存的閥值限制為止。 如果用戶進程在搜索LRU列表找到一個臟緩存,它移動緩存到寫列表,然后繼續(xù)搜索。當進程找到空閑緩存時,它將磁盤上的數據塊讀取到緩存中,并移動這個緩存到LRU列表的最近經常使用端。 如果一個Oracle用戶進程查找達到緩存閥值限制也沒有知道空閑緩存,進程停止搜索LRU列表,給DBW0后臺進程發(fā)信號將某些臟塊寫入磁盤。 LRU策略和全表掃描 當用戶進程執(zhí)行一個全表掃描,它讀取表的塊到緩存中,并將它們放到LRU列表的LRU端(而不是MRU端)。這是因為一個全表掃描通常只有少數情況下才需要,所以塊應該快速從緩存中移除,留下更多的空間給經常使用的塊。 你可以控制基于表掃描的表塊的默認行為。在表或聚集創(chuàng)建時使用CACHE子句就可以指定表塊在全表掃描期間放置在LRU列表的MRU端。你可以對經常查找的小表或者大的靜態(tài)歷史表指定這種行為來在順序訪問表時減少I/O。 數據庫高速緩存的大小 Oracle支持一個數據庫中多個塊大小。SYSTEM表空間使用的是標準塊大小。你可以通過設定初始化參數DB_BLOCK_SIZE來指定標準塊大小。合法塊大小為2K到32K。 如果需要的話,你可以設置兩個額外的緩沖池,通過DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE來設置保持(KEEP)和循環(huán)(RECYCLE)池。這3個參數是相互獨立的。 非標準塊大小的緩存的尺寸和數量可以通過下列參數指定: DB_2K_CACHE_SIZE DB_4K_CACHE_SIZE DB_8K_CACHE_SIZE DB_16K_CACHE_SIZE DB_32K_CACHE_SIZE 每個參數指定了對應塊大小的緩存尺寸。 設置塊和緩存大小的例子 DB_BLOCK_SIZE=4096 DB_CACHE_SIZE=1024M DB_2K_CACHE_SIZE=256M DB_8K_CACHE_SIZE=512M 在前面的例子中,參數DB_BLOCK_SIZE設置了數據庫的標準塊大小為4K。標準塊大小的緩存大小為1024M。另外,2K和8K塊的緩存也定義了,分別為256MB和512MB。 注意:DB_nK_CACHE_SIZE參數不能用于標準塊大小的緩存大小的設置。如果參數DB_BLOCK_SIZE的值是nK,設置DB_nK_CACHE_SIZE是非法的。標準塊的緩存大小總是由DB_CACHE_SIZE的值指定。 緩存有一個限制值,所以不是所有磁盤上的數據都能放到緩存中。當緩存充滿時,隨后的cache miss會導致Oracle將緩存中存在的臟塊寫入磁盤,騰出空間來容納新的數據。(如果一段緩存不臟,那么在新塊讀入緩存之前不需要將其寫入到磁盤)。隨后對于已經寫入磁盤的任何數據的訪問都會導致cache miss。 緩存的大小會影響以cache hit方式訪問數據的可能性。如果Cache很大,它更可能包含需要訪問的數據。提高Cache的尺寸會提高cache hit訪問數據的百分比。 你可以在實例運行時修改buffer cache的大小,而不需要關閉數據庫。修改bufer cache大小可以使用ALTER SYSTEM語句。更多的信息,可以參考“控制SGA的內存使用”。 使用固定視圖V$BUFFER_POOL來跟蹤不同cache組件的大小和任何將要發(fā)生的重新定義大小的操作。 多個緩沖池 你可以使用幾個緩沖池來定義數據庫buffer cache,這些緩沖池可以讓數據保存在buffer cache中或者數據塊在緩存中只保存一次(使用之后就清除,留給新數據使用)。特定的模式對象(表、聚集、索引和分區(qū))可以分配合適的緩沖池來控制它們的數據庫在cache中如何老化: u KEEP緩沖池:在內存中保持模式對象的數據塊 u RECYCLE緩沖池:立即清理不再使用的數據塊出內存 u DEFAULT緩沖池:包含沒有分配任何緩沖池的模式對象的數據塊,和顯式分配到DEFAULT緩沖池的模式對象一樣處理。 配置KEEP和RECYCLE緩沖池的初始化參數是DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE。 注意:多緩沖池只對標準塊有效,非標準塊Cache只有一個DEFAULT池。 重做日志緩存重做日志緩存是SGA中保存數據庫的修改信息的循環(huán)緩存。這些信息是重做條目。重做條目包含由INSERT、UPDATE、DELETE、CREATE、ALTER或DROP操作造成的修改的重構或者重做信息。重做條目必要時可以用于數據庫恢復。 重做記錄由Oracle數據庫進程從用戶的內存空間拷貝到SGA的重做日志緩沖中。重做記錄在緩存中按照順序保存。后臺進程LGWR將重做日志緩存寫入到磁盤上的當前活動的重做日志文件中(一組文件)。 初始化參數LOG_BUFFER指定了重做日志緩存的大?。ㄗ止?jié))。通常來說,大尺寸可以降低日志文件I/O,特別是長事務或多個事務時。默認值是512K和CPU數目乘以128K兩者的最大值。 共享池(Shared Pool)共享池是SGA中的一部分,包含庫緩存、數據字典緩存、并行執(zhí)行消息的緩存、控制結構。 共享池的大小由初始化參數SHARED_POOL_SIZE來指定。32位平臺的默認值為8M,64位平臺的默認值為64M。提高這個參數的大小可以提高共享池保留的內存數量。 庫緩存庫緩存包括共享SQL區(qū)域、私有SQL區(qū)域(在使用共享服務器的情況下)、PL/SQL過程和包、諸如鎖和庫緩存句柄的控制結構。 共享SQL區(qū)域對于所有用戶都可以訪問,所以庫緩存包含在SGA的共享池中。 共享SQL區(qū)域和私有SQL區(qū)域Oracle中每個SQL語句在共享SQL區(qū)域和私有SQL區(qū)域中執(zhí)行。Oracle可以識別兩個用戶執(zhí)行的相同的SQL語句,并對于這些用戶重用共享SQL區(qū)域。但是每個用戶必須有語句私用SQL區(qū)域的一個拷貝。 共享SQL區(qū)域一個共享SQL區(qū)域包含一個給定SQL語句的解析樹和執(zhí)行計劃。Oracle通過對多次使用的SQL語句使用同一個共享內存區(qū)域來節(jié)省內存,這種情況在多個用戶同時運行一個應用時經常出現。 Oracle在一個SQL語句被解析后,就會從共享池分配內存將其保存在共享SQL區(qū)域中。分配內存的大小依賴于語句的復雜程度。當整個共享池都被分配了,Oracle會使用一個改進的LRU(最近最少使用)算法來從池中釋放一些條目,直到可以容納新語句的共享內存區(qū)域為止。如果Oracle釋放了一個共享SQL區(qū)域,相關SQL語句下次執(zhí)行時必須重新解析和重新分配另外一塊共享SQL區(qū)域。 PL/SQL程序單位和共享池Oracle執(zhí)行PL/SQL程序單位(過程、函數、包、匿名塊、數據庫觸發(fā)器)和處理單獨SQL語句方式類似。Oracle分配一個共享區(qū)域來保存程序單位的解析、編譯格式。Oracle還分配一個私有區(qū)域來保存運行程序單位的會話的信息,包括正在執(zhí)行的SQL的本地、全局和包變量(也可以說是包實例)和緩存。如果多個用戶運行同一個程序單位,那么所有用戶使用同一個共享區(qū)域,而每個用戶保存他或者她的私有SQL區(qū)域的一個單獨拷貝,這里保存著他或她的會話信息。 PL/SQL程序單位里面的單獨SQL語句處理起來和前一部分描述的一樣。不管它們是否來源于PL/SQL程序單位,這些SQL語句使用一個共享區(qū)域來保存它們的解析樹,每個語句使用一個私有區(qū)域來保存語句所在會話的信息。 數據字典緩存數據字典是一些包含數據庫信息、數據庫結構和用戶信息的表、視圖的集合。Oracle在SQL語句解析時經常訪問數據字典。這個訪問對于Oracle持續(xù)運行是必需的。 數據字典經常訪問,所以Oracle在內存中分配了兩個區(qū)域來專門保存字典數據。一個區(qū)域叫做數據字典高速緩存,也叫做行高速緩存(因為它保存了數據行,而不是保存整個塊的數據的一個緩存)。另一個內存區(qū)域是在庫高速緩存中保存數據字典數據的。所有的Oracle用戶進程共享這兩個高速緩存(cache)來訪問數據字典信息。 共享池中內存的釋放和重新使用通常來說,共享池中的任何條目(共享SQL區(qū)域或者字典行)都一直保持,除非通過改進的LRU算法清理出去。如果共享池必須為新的條目分配空間時,不再經常使用的內存條目就會被釋放。一個改進的LRU算法允許被很多會話使用的共享池條目只要是有用的,就一直保存在內存中,即使創(chuàng)建這個條目的原始進程結束也是如此。因此一個多用戶Oracle系統(tǒng)的SQL語句處理和開銷是非常小的。 當一個SQL語句提交給Oracle來執(zhí)行時,Oracle自動執(zhí)行下列的內存分配步驟: 1、Oracle檢查共享池來看共享內存區(qū)域是否已經存在相同的語句。如果找到了,共享內存區(qū)域就被隨后執(zhí)行的語句實例使用。如果沒有這個語句的共享SQL區(qū)域,Oracle會在共享池中分配一個共享SQL區(qū)域。任一情況下,都會創(chuàng)建對應共享SQL區(qū)域的私有SQL區(qū)域。 注意:共享內存區(qū)域能夠從共享池中清除,甚至對應于一個一段時間不再使用的打開的游標對應的共享SQL區(qū)域也是如此。如果這個游標隨后被調用而需要運行它的語句,Oracle重新解析語句,共享池分配一個新的共享SQL區(qū)域。 2、Oracle基于會話分配一個私有SQL區(qū)域。私有SQL區(qū)域的位置依賴于構成連接的會話的類型。 Oracle還在這些情況下從共享池中清理共享SQL區(qū)域: u 當使用ANALYZE語句來更新或者刪除表、聚集、索引的統(tǒng)計信息,所有包含分析的模式對象對應的共享SQl區(qū)域會被從共享池中清理出去。清理出去的語句下一次運行時,語句在新的共享SQL區(qū)域中分析來反映模式對象的新的統(tǒng)計信息。 u 如果SQL語句引用的模式對象最近被修改過結構,共享SQL區(qū)域就是無效的(標識為無效),下次語句執(zhí)行時必須被重新解析。 u 如果你修改了數據庫的全局數據庫名字,共享池的所有信息都被清理出去 u 管理員可以手工的清除共享池的所有信息來在不需要關閉當前實例的情況評估性能。ALTER SYSTEM FLUSH SHARED_POOL語句就是用來干這個的。 大池數據庫管理員可以配置一個可選的內存區(qū)域(叫做大池)來為下列情況提供大內存分配: u 共享服務器和Oracle XA接口(多個數據庫交互的事務會用到) u I/O服務器進程 u Oracle備份和恢復操作 通過在大池中為共享服務器、Oracle XA或者并發(fā)查詢緩存分配內存,Oracle可以使用共享池集中緩存共享SQL,避免收縮共享SQL緩存導致性能瓶頸。 另外,Oracle備份和恢復操作、I/O服務器進程、并發(fā)緩存需要分配的緩存可能達幾百MB,大池比共享池更適合這樣大內存請求。 大池并沒有LRU列表。它和共享池的備用區(qū)域不同,這個區(qū)域和其他共享池中的內存分配一樣使用了LRU列表。 Java池Java池內存是JVM內的所有會話級別的Java代碼和數據使用的服務器內存。Java池內存使用方式依賴于Oracle服務器的運行模式。 Java池顧問統(tǒng)計提供了Java使用的庫緩存信息,推測Java池如何變化能影響的解析比例。Java池顧問在statistics_level設置為TYPICAL或者更高時內部開啟。如果顧問關閉,統(tǒng)計信息復位。 流池在一個單獨數據庫中,你可以聲明一個流池,流池是從SGA中的一個池中分配一個流內存。要配置流池的話,使用初始化參數STREAMS_POOL_SIZE來指定池的大小(字節(jié)數)。如果流池沒有定義,那么流第一次使用時會自動創(chuàng)建。 如果設置了SGA_TARGET,那么SGA內存中流池來源于SGA的全局池。如果沒有設置SGA_TARGET,然后SGA的流池從其他高速緩存中分配。這個分配只發(fā)生在第一次使用流時,分配量是共享池大小的10%。 控制SGA的內存使用動態(tài)SGA提供了對于增加和減少Oracle物理內存使用的更多控制。包括動態(tài)buffer cache、共享池和大池,動態(tài)SGA允許下列情況: u SGA可以根據數據庫管理員語句增長,上限為操作系統(tǒng)最大內存和SGA_MAX_SIZE的值。 u SGA可以根據數據庫管理員語句收縮,下限為Oracle預定義最小值,通常是操作系統(tǒng)限制優(yōu)先。 u SGA池和buffer cache都可以在運行時根據Oracle管理策略的一些內部機制來增長和收縮。 其他SGA初始化參數你可以使用多個初始化參數來控制SGA任何使用內存。 物理內存 LOCK_SGA參數將SGA鎖定在物理內存中(即SGA只使用物理內存) SGA開始地址 參數SHARED_MEMORY_ADDRESS和HI_SHARED_MEMORY_ADDRESS指定了SGA運行時的開始地址。這些參數很少使用。在64位平臺上,HI_SHARED_MEMORY_ADDRESS指定了64位地址的高32位地址。 擴展Buffer Cache機制 參數USE_INDIRECT_DATA_BUFFERS對32位平臺啟用擴展bufer cache機制,這樣就可以支持多于4G的物理內存。在不支持那么多物理內存的平臺上,忽略這個參數。 程序全局區(qū)概述(PGA)程序全局區(qū)(PGA)是一個包含服務器進程的數據和控制信息的內存區(qū)域。這是Oracle服務進程啟動時創(chuàng)建的非共享內存。它是這個服務器專用的內存,只能由Oracle代碼代表它讀寫。一個Oracle實例的每個服務器進程分配的PGA內存總和也叫做實例分配的聚集PGA內存。 PGA的目錄PGA的內存條目針對是否啟用了共享服務器而不同。但通常來說,PGA內存可以按照以下分類: 私有SQL區(qū)域私有SQL區(qū)域包含綁定信息和運行時內存結構。每個執(zhí)行SQL語句的會話都有一個私有SQL區(qū)域。每個提交相同SQL語句的用戶都有他或她自己的私有SQL區(qū)域,并且共享同一個共享SQL區(qū)域。因而,一個共享SQL區(qū)域可以對應于多個私有SQL區(qū)域。 一個游標的私有SQL區(qū)域分成兩個部分,它們的生命周期不同: u 持久區(qū)域,包括諸如綁定信息。在游標關閉時釋放 u 運行時區(qū)域,只有在執(zhí)行結束時釋放。 Oracle在執(zhí)行請求的第一步創(chuàng)建運行時區(qū)域。對于INSERT、UPDATE、DELETE語句,Oracle在語句運行之后釋放運行時區(qū)域。對于查詢來說,Oracle只有在所有行都獲取之后或者查詢被取消之后才會釋放運行時區(qū)域。 私有SQL區(qū)域的位置依賴于創(chuàng)建會話的連接類型。如果會話通過專用服務器連接,私有SQL區(qū)域位于服務器進程的SGA中。但是,如果會話通過共享服務器連接,私有SQL區(qū)域的一部分保存在SGA中。 游標和SQL區(qū)域Oracle預編譯程序或者OCI程序的應用開發(fā)人員可以顯示的打開具體的私有SQL區(qū)域的游標或句柄,在程序執(zhí)行期間像一個命名資源那樣使用它們。Oracle隱式執(zhí)行的一些SQL語句的遞歸游標也使用共享SQL區(qū)域。 私有SQL區(qū)域的管理是用戶進程的責任。雖然一個用戶進程可以分配的私有SQL區(qū)域數量總是由初始化參數OPEN_CURSORS限制,但私有SQL區(qū)域的分配和釋放很大程度上依賴于你使用的應用程序工具。這個參數的默認值為50. 一個私有SQL區(qū)域一直存在,除非對應的游標關閉或者語句句柄被釋放。Oracle在語句完成時釋放了運行時區(qū)域,但持久性區(qū)域還保持等待狀態(tài)。應用開發(fā)人員需要管理所有的不再使用的打開游標來釋放持久性區(qū)域和最小化應用程序用戶需要的內存數量。 會話內存會話內存是一個保存會話變量(登陸信息)和其他會話相關信息的內存。對于共享服務器,會話內存是共享的,而不是私有的。 SQL工作區(qū)域對于復雜的查詢(例如決策支持查詢),運行時區(qū)域的一大部分用于內存密集型操作符分配的工作區(qū)域,例如: u 排序操作符(order by,group-by,rollup,window,function) u 哈希關聯(lián) u 位圖合并 u 位圖創(chuàng)建 例如,一個排序操作符使用一個工作區(qū)域(有時叫做排序區(qū)域)來執(zhí)行一系列行在內存中的排序。類似的,哈希關聯(lián)操作符使用一個工作區(qū)域(也叫做Hash區(qū)域)來從它的左輸入來構建hash表。如果這兩個操作符操作的數據量不能都放在工作區(qū)域中,然后輸入數據會分成更小的一些片。這導致某些數據片在內存中處理,而剩下的部分放在臨時磁盤存儲上,等待后續(xù)執(zhí)行。雖然位圖操作符在它們工作區(qū)太小時不會溢出到磁盤,但是它們的復雜程度和工作區(qū)域的大小成反比。因而,這些操作符在大工作區(qū)域中運行起來更快。 工作區(qū)域的大小可以控制和調整。通常,大數據庫區(qū)域可以提高特定的大量消耗內存的操作符的性能。理想情況下,工作區(qū)大小應該足夠容納輸入數據和相關SQL操作符分配的輔助存儲結構。如果做不到,會增加反應時間,因為輸入數據的一部分必須溢出到臨時磁盤存儲上。在極端情況下,如果工作區(qū)域相對輸入數據來說太小,數據片必須多次裝入。這會出人意料的增加操作符的反應時間。 專用服務器模式下的PGA內存管理你可以整體上自動管理SQL工作區(qū)域的大小。數據庫管理員可以通過設置初始化參數PGA_AGGREGATE_TARGET來簡化設置PGA內存的總體尺寸的工作。指定值(例如 2G)是Oracle實例的總體值,Oracle視圖確保所有服務器進程分配的PGA內存總量不能超過這個值。 注意:在早期版本中,數據庫管理員通過下列參數控制SQL工作區(qū)域的最大值:SQL_AREA_SIZE,HASH_AREA_SIZE,BITMAP_MERGE_AREA_SIZE和CREATE_BITMAP_AREA_SIZE。設置這些參數是非常困難的,因為最優(yōu)的最大的工作區(qū)域大小要在數據輸入大小和系統(tǒng)中活動的全部工作區(qū)域之間選擇。這兩個因素在工作區(qū)域之間和不同的時間段都會不同。因而,不同的*_AREA_SIZE參數在最好的情況下也很難調整。 通過PGA_AGGREGATE_TARGET,所有專用會話的工作區(qū)域的大小是自動調整的,所有的*_AREA_SIZE都被忽略。在任何給定的時間內,實例中活動的工作區(qū)域的總體PGA內存數量自動從參數PGA_AGGREGATE_TARGET中分配。這個數量是指PGA_AGGREGATE_TARGET減去系統(tǒng)其他組件分配的PGA內存(例如,會話分配的PGA內存)。剩下的PGA內存為每個活動工作區(qū)域根據他們需要的內存分配給它們。 注意:初始化參數WORKAREA_SIZE_POLICY是一個會話和系統(tǒng)級別的參數,只能有兩個值MANUAL和AUTO。默認是AUTO。數據庫管理員可以設置PGA_AGGREGATE_TARGET,然后從自動內存管理模式轉回到手工內存管理模式。 有些固定視圖和列可以提供PGA內存的使用統(tǒng)計信息。在PGA_AGGEGATE_TARGET被設置時,可以啟動大部分統(tǒng)計信息。 u 工作區(qū)域內存的分配和使用統(tǒng)計信息可以在下列動態(tài)性能視圖中顯示: V$SYSSTAT V$SESSTAT V$PGASTAT V$SQL_WORKAREA V$SQL_WORKAREA_ACTIVE u 視圖V$PROCESS的下面三列報告了一個Oracle進程分配和使用的PGA內存: PGA_USED_MEM PGA_ALLOCATED_MEM PGA_MAX_MEM 注意:自動PGA內存管理模式在共享和專用服務器下都可以分配工作區(qū)域。 專用和共享服務器內存分配在一些細節(jié)上依賴于是否使用了專用或者共享服務器架構。表8-1顯示了其中的區(qū)別。 表8-1 共享和專用服務器中內存分配的不同 
 軟件代碼區(qū)域軟件代碼區(qū)域是保存正在運行或可以運行的代碼的內存區(qū)域。Oracle代碼保存在軟件代碼區(qū)域,它和用戶程序的位置不同,是更專用或更加保護的位置。 軟件區(qū)域大小通常是固定的,只有在軟件升級或者重新安裝時改變。這些區(qū)域需要的尺寸和操作系統(tǒng)有關。 軟件區(qū)域是只讀的,可以共享使用,也可以不共享使用。盡可能的情況下,Oracle代碼是共享的,所有的Oracle用戶都可以訪問,這樣內存中就不用保存多份拷貝了。這樣可以節(jié)省物理內存和提升總體性能。 用戶程序也可以共享,也可以不共享。某些Oracle工具和公共程序(如Oracle窗體和SQL *PLUS)可以共享,但某些不能。Oracle多個實例如果運行在一臺機器上可以使用相同的Oracle代碼區(qū)域。 注意:共享軟件安裝的選項不是在所有的操作系統(tǒng)上都可用(例如,在PC的windows系統(tǒng)上)。 查看你的Oracle操作系統(tǒng)規(guī)格文檔來查找更多的信息。 | 
|  | 
來自: 月影斜 > 《Oracle 10.2 概念》