1. 程式人生 > >關於oracle sga設定的總結,很經典--轉

關於oracle sga設定的總結,很經典--轉

關於oracle sga設定的總結,很經典--轉 說明:
本總結不針對特例,僅對伺服器只存在OS + ORACLE 為例,如果存在其他應用請酌情考慮。寫這個也是因為近來這種重複性的問題發生的太多所導致的。

首先不要迷信STS、OCP SG以及某些專家給出的任何建議、記憶體百分比的說法。基本掌握的原則是:

l          data buffer 通常可以儘可能的大

l          shared_pool_size 要適度

l          log_buffer 通常大到幾百K到 1M就差不多了

設定之前,首先要明確2個問題
1:除去OS和一些其他開銷,能給ORACLE使用的記憶體有多大?
2:Oracle是64 bit 還是 32 bit ?32bit 通常 SGA有 1.7G 的限制(某些OS有特定處理或者

WINDOWS上有特定設定可以支援到2G以上甚至達到3.7G,本人無這方面經驗)。

下面是我的Windows2000下的Oracle :

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
PL/SQL Release 8.1.7.0.0 - Production
CORE 8.1.7.0.0 Production
TNS for 32-bit Windows: Version 8.1.7.0.0 - Production
NLSRTL Version 3.4.1.0.0 - Production

SQL>

windows上存在32bit的限制,如AIX、HP-UX 等有明確的64 bit OS 和ORACLE的版本,32 bit Oracle可以裝在64 bit OS 上,64 bit Oracle不能裝在32 bit OS上。

不管Oracle是32 bit 還是 64 bit 的,假定應用存在沒有很好的使用bind var 的情況,也不能設定 shared_pool_size 過大,通常應該控制在100M--200M,除非是 ORACLE ERP 一類的使用了很多儲存過程函式、包 ,這樣的很大的系統,可以考慮增大shared_pool_size,但是如果超過500M可能是危險的,達到1G幾乎就會造成CPU的嚴重負擔,系統甚至癱瘓。所以shared_pool_size 如果超過200M還命中率不高,那麼應該從應用上找原因而不是一味的增加記憶體,shared_pool_size 過大主要增加了

管理負擔和latch 的開銷。

log_buffer :128K -- 1M 之間通常問題不大,不應該太大。

large_pool_size :如果不設定MTS,通常在 RMAN 、OPQ 會使用到,但是在10M --50M 應該差不多了。假如設定 MTS,則由於 UGA 放到large_pool_size 的緣故,這個時候依據 session最大數量和 sort_ares_size 等引數設定,必須增大large_pool_size 的設定,可以考慮為 session * (sort_area_size + 2M)。這裡要提醒一點,不是必須使用MTS,我們都不主張使用MTS,尤其同時線上使用者數小於500的情況下。

java_pool_size : 若不使用java,給30M通常就夠了。

data buffer :在做了前面的設定後,凡可以提供給Oracle的記憶體,都應該給data buffer = (db_block_size * db_block_buffers) 在9i 中可以是 db_cache_size。

還有2個重要引數我們需要注意:

sort_area_size
hash_area_size
這兩個引數在非MTS下都是屬於PGA ,不屬於SGA。它是為每個session單獨分配的,在我們的伺服器上除了OS + SGA,一定要考慮這兩部分。

(****) : OS 使用記憶體+ SGA + session*(sort_area_size + hash_area_size + 2M) < 總物理RAM 為好 。

這樣歸結過來,假定Oracle是 32 bit ,伺服器RAM大於2G ,注意你的PGA的情況,則建議:

shared_pool_size + data buffer +large_pool_size + java_pool_size < 1.6G

再具體化,注意滿足上面(****) 的原則的基礎上可以參考如下設定:
如果512M RAM
建議 shared_pool_size = 50M, data buffer = 200M ;

如果1G RAM
shared_pool_size = 100M , data buffer = 500M ;

如果2G RAM
shared_pool_size = 150M ,data buffer = 1.2G。

實體記憶體再大已經跟引數沒有關係了 。

舉例來說:
假定64 bit ORACLE

記憶體4G
shared_pool_size = 200M , data buffer = 2.5G

記憶體8G
shared_pool_size = 200M , data buffer = 5G

記憶體 12G
shared_pool_size = 300M , data buffer = 8G

   
 
Top

4 樓shuen(ShiningStone)回覆於 2005-09-04 18:04:32 得分 0 我的系統是WIN2000   SERVER+   ORACLE   9I       RAM     2G  
  其中有些引數配置:  
   
  db_cache_size               =                   25165824  
  shared_pool_size   =   50331648  
   
  這些都是預設配置,沒改動多  
  以前系統問題不大,可能是處理的資料不大  
  但現在有些表資料達到了幾十萬行  
  多個使用者執行SQL查詢就很慢,但系統狀態顯示伺服器的CUP和記憶體的佔用率都不高  
  是不是配置存在很大的問題???  
  謝謝
Top


5 樓shuen(ShiningStone)回覆於 2005-09-04 18:08:17 得分 0 db_cache_size   的大小修改不了,怎麼回事?
Top

6 樓dnmyg2003(毛毛)回覆於 2005-09-06 15:59:52 得分 50在設定新系統得SGA大小時,我們不是使用oracle建議值,而是使用下列經驗法則:  
  伺服器實體記憶體×0.55=要分配給所有SGA的記憶體總量(TSGA)  
  TSGA/伺服器上的oracle例項個數=每個例項的總SGA大小(TSGAI)  
  使用TSGAI值,然後就可以計算出每個例項的SGA大小:  
  TSGAI×0.45=已分配給shared   pool的總記憶體  
  TSGAI×0.45=已分配給database   buffer   cache的總記憶體  
  TSGAI×0.10=已分配給redo   log   buffer的總記憶體  
  在大多數情況中,為redo   log   buffer保留SGA空間的10%將是不必要的。但是,在調整統計資料可使用之後,大家隨時可以從這個區域中取走記憶體,並把它們分配給shared   pool、database   buffer   cache和large   pool。  
  考慮事項  
  這麼計算的目的是為了充分利用現有記憶體,同時又仍給作業系統、oracle後臺程序、使用者伺服器程序以及執行在該伺服器上的其他任何非oracle程序保留充足的記憶體。作業系統所需要的記憶體量在Windows   NT系統(一般需要較多記憶體)到UNIX型系統(一般需要較少記憶體)之間變化很大,因此大家可能需要相應地調整自己的計算。這條經驗法則在總記憶體小於1GB的伺服器上非常適用。在具有1GB以上記憶體量的伺服器上,大家應該把TSGA計算中使用的55%初始縮小率改成一個較大的值,比如60%~75%   。    


##################################
資料塊快取區(data   block   buffer   cache)是SGA中的一個快取記憶體區域,用來儲存從資料庫中讀取資料段的資料塊(如表、索引和簇)。資料塊快取區的大小由資料庫伺服器init.ora檔案中的DB_BLOCK_BUFFERS引數決定(用資料庫塊的個數表示)。在調整和管理資料庫時,調整資料塊快取區的大小是一個重要的部分。因為資料塊快取區的大小固定,並且其大小通常小於資料庫段所使用的空間,所以它不能一次裝載下記憶體中所有的資料庫段。通常,資料塊快取區只是資料庫大小的1   %~2   %,Oracle使用最近最少使用(   LRU,least   recently   used)演算法來管理可用空間。當儲存區需要自由空間時,最近最少使用塊將被移出,新資料塊將在儲存區代替它的位置。通過這種方法,將最頻繁使用的資料儲存在儲存區中。然而,如果SGA的大小不足以容納所有最常使用的資料,那麼,不同的物件將爭用資料塊快取區中的空間。當多個應用程式共享同一個SGA時,很有可能發生這種情況。此時,每個應用的最近使用段都將與其他應用的最近使用段爭奪SGA中的空間。其結果是,對資料塊快取區的資料請求將出現較低的命中率,導致系統性能下降。  
  資料庫物件的資訊儲存在資料字典表中,這些資訊包括使用者帳號資料、資料檔名、段名、盤區位置、表說明和許可權,當資料庫需要這些資訊(如檢查使用者查詢一個表的授權)時,將讀取資料字典表並且將返回的資料儲存在字典快取區的SGA中。資料字典快取區通過最近最少使用(LRU)   演算法來管理。字典快取區的大小由資料庫內部管理。字典快取區是SQL共享池的一部分,共享池的大小由資料庫檔案init.ora中的SHARED_POOL_SIZE引數來設定。如果字典快取區太小,資料庫就不得不反覆查詢資料字典表以訪問資料庫所需的資訊,這些查詢稱為迴圈呼叫(recuesive   call),這時的查詢速度相對字典快取區獨立完成查詢時要低。  
   
  SHARED_POOL_SIZE由前者組成,至於大小要看你資料庫的用途和業務及配置。  
   
 
Top

2 樓joachern(程式人生)回覆於 2003-07-23 09:01:28 得分 0 自己up!!
Top

3 樓maohaisheng(蟲族:無名小蟲)回覆於 2003-07-23 13:22:31 得分 10這兩個引數沒有絕對的關係,一樓已經說得很清楚了
Top

4 樓luckysxn(堅持到底)回覆於 2003-07-23 15:28:00 得分 30ORACLE     8.0.X     版本      
     
  SGA=((db_block_buffers     *     block     size)+(shared_pool_size+large_pool_size+log_buffers)+1MB      
     
  ORACLE     8.1.X     版本      
     
  SGA=((db_block_buffers     *     block     size)+(shared_pool_size+large_pool_size+java_pool_size+log_buffers)+1MB      
     
  理論上SGA可佔OS系統實體記憶體的1/2——1/3,我們可以根據需求調整      
     
  我推薦SGA=0.45*(OS     RAM)      
     
  假設伺服器執行ORACLE     8.1.X     版本,     OS系統記憶體為2G     MEM,     db_block_size     是8192     bytes,          
  除了執行ORACLE資料庫外,     沒有其它的應用程式或伺服器軟體.      
     
  這樣SGA合計約為921M     (     0.45*2048M     ),          
     
  設shared_pool_size     300M     (300*1024*1024     bytes)      
     
  設database     buffer     cache     570M     (72960*8192     bytes)      
     
    initorasid.ora檔案裡具體各引數如下:      
     
  shared_pool_size     =     314572800      
  #     300     M      
     
  db_block_buffers     =     72960      
  #     570     M      
     
  log_buffer     =     524288      
  #     512k     (128K*CPU個數)      
     
  large_pool_size     =     31457280      
  #     30     M      
     
  java_pool_size     =     20971520      
  #     20     M      
     
  sort_area_size     =     524288      
  #     512k     (65k--2M)      
     
  sort_area_retained_size     =     524288      
  #     MTS     時     sort_area_retained_size     =     sort_area_size      
     
  SUN     Solaris裡/etc/system檔案裡的幾個引數同樣跟記憶體分配有關      
     
  ORACLE安裝時預設的設定:     建議修改的設定:          
  set     shmsys:shminfo_shmmax=4294967295          
  set     shmsys:shminfo_shmmin=1          
  set     shmsys:shminfo_shmmni=100          
  set     shmsys:shminfo_shmseg=15          
  set     semsys:seminfo_semmns=200          
  set     semsys:seminfo_semmni=70          
  set     ulimit=3000000              
  set     semsys:seminfo_semmni=315      
  set     semsys:seminfo_semmsl=300      
  set     semsys:seminfo_semmns=630      
  set     semsys:seminfo_semopm=315      
  set     semsys:seminfo_semvmx=32767      
  set     shmsys:shminfo_shmmax=4294967295      
  set     shmsys:shminfo_shmmni=315      
  set     shmsys:shminfo_shmseg=10      
  set     shmsys:shminfo_shmmin=1          
     
  其中這些引數的含義      
     
  shmmax     -     共享記憶體段,建議設大點,     達到最大SGA      
  shmmin     -     最小的共享記憶體段.      
  shmmni     -     共享記憶體標誌符的數量.      
  shmseg     -     一個程序可分配的最大記憶體段數.      
  shmall     -     最大可允許的記憶體數,比SGA還要大.      
  semmns     -     訊號燈,跟ORACLE的PROCESS數有關.      
  semmsl     -     一個訊號燈中最大的訊號燈數.      
     
     
  ---------------------------------------------------------------      
     
  分析你的init.ora      
  shared     pool         31,457,280         #30M      
  data     buffers     4326*8192=     35,438,592     #35M      
  large     pool         614,400                 #600K      
  #多執行緒      
  mts_dispatchers     =     "(protocol=TCP)(tick=15)(pool=true)"      
  ---------------------      
  這樣,如果你認為你的語句已經優化了,如果你的記憶體也不是太大的話。      
  對於     shared     pool和data     buffers的大小已經夠了。      
  但是,你又用了多執行緒,又只把large     pool配置了600k      
  你要麼先把多執行緒去掉,要麼把large     pool加大(30M)試試(多執行緒用到了large     pool)。      
  最後,把你的init檔案中的一些引數還調整一下      
  db_file_multiblock_read_count     =     8         #可以加大到16     or     32試試      
  把      
  oracle_trace_collection_name     =     ""      
  system_plan      
  這注釋掉      
 
Top

5 樓woodpan(木頭)回覆於 2003-07-23 19:00:39 得分 10shared_pool_size   以位元組為單位,指定共享池的大小。共享池包含如:   共享遊標、儲存的過程、控制結構和並行執行訊息緩衝區等物件。較大的值能改善多使用者系統的效能。這個值不需要太大,一般不超過150M  
  db_block_buffers   緩衝區快取記憶體中   Oracle   塊的數量。database_buffers=db_block_buffers×db_block_size.這個值越大越好,只要整個SGA不超過系統實體記憶體限制,給最大值  

##############################
資料快取記憶體區命中率
  --計算公式:1-(physical reads / (db block gets + consistent gets))
  --命中率應大於0.90最好
  select name,value
  from v$sysstat
  where name in ('physical reads','db block gets','consistent gets')
  /
  --共享區庫快取區命中率
  --計算公式:SUM(pins - reloads) / SUM(pins)
  --命中率應大於0.99
  select sum(pins-reloads)/sum(pins)
  from v$librarycache
  /
  --共享區字典快取區命中率
  --計算公式:SUM(gets - getmisses - usage -fixed) / SUM(gets)
  --命中率應大於0.85
  select sum(gets-getmisses-usage-fixed)/sum(gets)
  from v$rowcache
  /
  --檢測回滾段的爭用
  --SUM(waits)值應小於SUM(gets)值的1%
  select sum(gets),sum(waits),sum(waits)/sum(gets)
  from v$rollstat
  /
  --檢測回滾段收縮次數
  select name,shrinks
  from v$rollstat, v$rollname
  where v$rollstat.usn = v$rollname.usn
  /
  --關於SGA的調優
  (****) : OS 使用記憶體+ SGA + session*(sort_area_size + hash_area_size + 2M) < 總物理RAM 為好
  log_buffer : 128K ---- 1M 之間通常問題不大,不應該太大
  large_pool_size :如果不設定MTS,通常在 RMAN 、OPQ 會使用到,但是在10M --- 50M 應該差不多了。
  java_pool_size : 若不使用java,給30M通常就夠了
  data buffer ,在做了前面的設定後,凡可以提供給oracle的記憶體,都應該給data buffer = (db_block_size * db_block_buffers)
  不能設定 shared_pool_size 過大,通常應該控制在200M--300M
  再具體化,注意滿足上面(****) 的原則的基礎上可以參考如下設定
  如果512M RAM
  建議 shared_pool_size = 50M, data buffer = 200M
  如果1G RAM
  shared_pool_size = 100M , data buffer = 500M
  如果2G
  shared_pool_size = 150M ,data buffer = 1.2G
  實體記憶體再大已經跟引數沒有關係了
  假定64 bit ORACLE
  記憶體4G
  shared_pool_size = 200M , data buffer = 2.5G
  記憶體8G
  shared_pool_size = 300M , data buffer = 5G
  記憶體 12G
  shared_pool_size = 300M-----800M , data buffer = 8G