OraclePGA原理及管理

atlantisholic發表於2011-04-10
一、 PGA 概念:
PGA 指程式全域性區,是伺服器程式( ServerProcess )使用的一塊包含資料和控制資訊的記憶體區域, PGA 是非共享的記憶體,在伺服器程式啟動或建立時分配,併為伺服器程式所專用。
PGA 的分配以及所儲存的資訊隨 Oracle 的工作狀態(專有模式和共享模式)不同而不同,但不管如何 PGA 通常可分為固定 PGA 和可變 PGA 區域,如果伺服器工作在專有伺服器模式下,那麼可變 PGA 就將分配在 PGA 自有區域內,如果工作在共享伺服器模式下,那麼可變 PGA 將分配在 SGA (程式全域性區)內,而在 PGA 自有區域內保留指向可變區域的地址指標。
再細分的話,那麼可變 PGA 區域有可以分為會話記憶體和私有 SQL 區,在會話記憶體中存放會話登入資訊以及其他一些資訊,對共享伺服器模式這部分資訊是共享的,而專有伺服器模式這部分是私有的。私有 SQL 區存放繫結變數資訊和查詢狀態以及查詢工作區等資訊,同樣對於共享伺服器模式這部分割槽域分配於 SGA 中。
私有 SQL 區的分配 Oracle 是通過遊標( Cursor )來完成,其實 PGA 的主要記憶體消耗就來自 Cursor ,但是遊標的開啟和釋放, Oracle 是不負責的,這部分工作完全交由使用者程式來處理。但是 Oracle 通過 OPEN_CURSORS 引數來控制開啟遊標的最大值。私有 SQL 區有可以再細分成永久區域和執行時區域,由於這部分割槽域完全由使用者程式來使用和分配,因此這部分割槽域也稱為 UGA (使用者全域性區)。
在永久區域中包含繫結變數等資訊,這部分記憶體只有在遊標被關閉時才會釋放。在執行時區域中,存放 SQL 執行時所需要的資訊,它在執行請求時首先建立, 其中包含了查詢執行狀態資訊, SQL WorkAreas (分組,排序,連線操作所使用的記憶體區域),對於 Insert/Update/Delete 等操作這部分割槽域在執行完畢後就會釋放,對於查詢操作則是在結果集返回後或者查詢被取消後返回。
在 UGA 區域中還存在一個子區域稱為 CGA (全域性呼叫區),這部分割槽域用於執行時執行一些低層操作時分配使用,比如 SQL 分析, Direct I/O Buffer 分配等。
二、 PGA 管理:
在 9i 之前 Oracle 通過 *_area_size 等引數對 PGA 進行管理,這些引數主要有 sort_zrea_size 、 hash_area_size 、 bitmap_merge_size 、 create_bitmap_area_size 等。在 Oracle 中可以通過 show parameter area_size 命令檢視這些設定。
從 9i 開始 Oracle 提供了一種新的 PGA 記憶體管理方式,即自動記憶體管理,從而大大簡化了 Oracle 記憶體管理,通過這個功能 Oracle 可以在總的記憶體使用限制下,實現 PGA 的自動管理與分配。
在 9i 之後 Oracle 通過 PGA_AGGREGATE_TARGET 引數來控制 PGA 記憶體自動管理的最大記憶體使用上限,通過 WORKAREA_SIZE_POLICY 引數來管理自動記憶體管理的開啟,當該引數設定為 AUTO 時將開啟自動記憶體管理,設定為 MANUAL 時將使用手動管理。在 9i 中 PGA_AGGREGATE_TARGET 引數只對專有伺服器模式有效,對共享伺服器模式將會自動失效,但是從 10G 開始 PGA_AGGREGATE_TARGET 引數對這兩種模式都會生效。
1、 自動 PGA 管理實現原理:
  Oracle 中對自動 PGA 管理採用反饋環( FeedBack Loop )演算法來實現。當程式開始 SQL 執行時,首先通過 Local Memory Manager 註冊一個 ActiveWorkArea Profile ,工作區 Profile 是進城與記憶體管理器之間通訊的唯一介面,活動 Profile 通過 Local Memory Manager 來維護,儲存在 SGA 中,有了這些 Profile ,後臺的 Global Memory Manager 就可以計算出一個在一定上限內並能提供較好效能的 Global Memory Bound ,這個值用於限制單個程式使用的 PGA 記憶體上限, Global Memory Manager 每個 3 秒鐘更新一次 Global Memory Bound , Local Memory Manager 得到 Global Memory Bound 後會計算出每個 Active Statement 所要分配的 PGA 記憶體,稱為 Expect Size ,然後每個 Active Statement 將會得到子所分得的 Expect Size ,並在該記憶體中進行運算。
2、 引數設定與記憶體分配:
在啟用自動管理的 Oracle 伺服器中,實際記憶體的分配與 PGA_AGGREGATE_TARGET 引數以及一些隱含引數的設定有關。主要有兩種分配方式(以 Oracle10gR2 和 11G 為例):
( 1 )、序列操作按照 min(5%*PGA_AGGREGATE_TARGET,100M) 方式分配;
( 2 )、並行操作按照 50%*PGA_AGGREGATE_TARGET/DOP 方式分配,其中 DOP 為並行度。
對於序列操作 5%*PGA_AGGREGATE_TARGET 這部分結果值受到 _smm_max_szie 隱含引數制約,該引數制定了自動管理下最大工作區限制,即 5%*PGA_AGGREGATE_TARGET 的記憶體大小不能超過 _smm_max_szie 值。具體限制如下:
          PGA_AGGREGATE_TARGET<=500M, _smm_max_szie=20%* PGA_AGGREGATE_TARGET
            PGA_AGGREGATE_TARGET[500M,1000M], _smm_max_szie=100M
            PGA_AGGREGATE_TARGET[1001M,2256M] ,_smm_max_szie=10%* PGA_AGGREGATE_TARGET
            PGA_AGGREGATE_TARGET>2560M, _smm_max_szie=250M
        對於並行那個操作,當 DOP<=5 時 _smm_max_szie 會生效,當 DOP 超過 5 時將取決於另一個引數 _smm_px_max_size 。
另外對於序列操作分配規則 min(5%*PGA_AGGREGATE_TARGET,100M) 中的 100M ,這個值取決於另一個隱含引數 _pga_max_size ,該引數制定了序列操作 PGA 的上限值(最大不能超過該值的 1/2 ,其實這個值就是 Global Memory Bound ), Oracle9iR2 中該值預設為 200M ,因此在 Oracle9i 中預設的序列操作最大將被分配 100M 。但是在 Oracle10GR2 中這個引數和 PGA_AGGREGATE_TARGET 相關,當改變 PGA_AGGREGATE_TARGET 引數後 _pga_max_size 將自動改變,但是當 PGA_AGGREGATE_TARGET>5G 後 _pga_max_size 引數將不再變化,在 1-5G 範圍內 _pga_max_size 值將會按照 20%* PGA_AGGREGATE_TARGET 設定增長。
3、 設定 PGA 引數:
可以通過 alter system set PGA_AGGREGATE_TARGET 命令來設定 PGA ,對於 PGA_AGGREGATE_TARGET 的設定 Oracle 提供如下建議對於 OLTP 系統 PGA_AGGREGATE_TARGET<= (總記憶體 *80% ) *20% ;對於 DSS 系統 PGA_AGGREGATE_TARGET<= (總記憶體 *80% ) *50%.
在 Oracle 中可以通過查詢 v$pga_target_advice 檢視來對不同 PGA 設定進行評估,給出 PGA 命中率和過載等評估資訊,以給出 PGA 設定建議如:
select a.PGA_TARGET_FOR_ESTIMATE / 1024 / 1024 PGAMB,
       a.PGA_TARGET_FACTOR,
       a.ESTD_PGA_CACHE_HIT_PERCENTAGE,
       a.ESTD_OVERALLOC_COUNT
  from v$pga_target_advice a;
        還可以通過查詢 v$pga_target_advice_histogram 檢視來對不同工作區大小取樣評估如:
        select a.PGA_TARGET_FACTOR,a.low_optimal_size/ 1024 low,
         round(a.high_optimal_size/ 1024 ) high ,
         a.estd_optimal_executions estd_mp,est_total_executions estd_exec
         from v$pga_target_advice_histogram a
         where a.PGA_TARGET_FACTOR= 0.25 and a.estd_total_executions> 0;
low_optimal_size: 為評估區間的 optimal 下限( bytes )
high_optimal_size: 為評估區間的 optimal 上限( bytes )
estd_optimal_executions :為評估區間 optimal 執行次數
est_total_executions :為評估區間估計執行總次數
PGA 中的執行有 3 種執行方式:
Optimal: 優化方式,所有處理都在記憶體中完成
Onepass: 大部分操作在記憶體中完成,但需要使用到磁碟操作
Multipass: 大量操作需要產生磁碟互動,最差方式
當你需要調整 PGA 或想要分析當前 PGA 時可以通過以下 SQL 產生一個當前系統的 PGA 指標:
select name,
       value,
       100 *
        (value / decode((select sum(value)
                         from v$sysstat
                        where name like 'workarea executions%'),
                       0,
                       NULL,
                       (select sum(value)
                           from v$sysstat
                         where name like 'workarea executions%'))) pct
  from v$sysstat
  where name like 'workarea executions%';
還可以通過下面的 SQL 語句查詢當前 PGA 記憶體消耗在什麼地方:
首先通過 OS 命令: ps –ef|grep LOCAL|head –l 查詢到當前例項的 Oracle 程式的程式號,如 2803
然後執行如下 SQL 語句:
select p.PROGRAM,p.pid,pm.category,pm.allocated,pm.used,pm.max_allocated
from v$process p,v$process_memory pm
where p.PID=pm.pid and p.SPID=2803;
 
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/ZengMuAnSha/archive/2010/04/15/5490230.aspx

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23071790/viewspace-692191/,如需轉載,請註明出處,否則將追究法律責任。

相關文章