標籤:
SGA(System Global Area)系統全域區。這是一個非常龐大的記憶體區間,也是為什麼開啟oracle之後佔用了很大記憶體的原因。
SGA分為不同的池,我們可以通過視圖v$sgastat查看,如下所示。
SQL> select pool ,sum(bytes) bytes from v$sgastat group by pool;
POOL BYTES
------------ ----------
956298240
java pool 16777216
streams pool 16777216
shared pool 199783376
large pool 16777216
SQL>
我們可以看到SGA由java pool(java 池)、shared pool(共用池)、large pool(大池) 和沒有名字的池組成。其中那塊沒有名字的記憶體又包括塊緩衝區(緩衝的資料庫塊)、重做日誌緩衝區和“固定SGA”區專用的記憶體。
oracle SGA記憶體結構如下所示:
下面逐個介紹:
1、Fixed SGA 固定SGA
可以把這個區想成是 SGA中的“自啟”區,Oracle在內部要使用這個區來找到SGA的其他區。換一句話,就是在這個記憶體裡面存有其他區的地址,我們可以通過訪問這個區來尋找到其他區的位置!
2、Redo Buffer 重做緩衝區
如果資料需要寫到線上重做日誌中,則在寫至磁碟之前要在重做緩衝區(redo buffer)中臨時緩衝這些資料。由於記憶體到記憶體的傳輸比記憶體到磁碟的傳輸快得多,因此使用重做日誌緩衝區可以加快資料庫的操作。我的理解是,如果沒有這個區,那我們操作一次資料庫就訪問一次磁碟,而如果有的話,則可以操作很多次之後才訪問一次磁碟。速度當然要快很多了。
3、Block Buffer 塊緩衝區快取
Oracle將資料庫塊寫至磁碟之前,另外從磁碟讀取資料庫塊之後,就會把這些資料庫Block Storage在塊緩衝區快取(block buffer cache)中。對我們來說,這是SGA中一個很重要的區。如果太小,我們的查詢就會永遠也運行不完。如果太大,又會讓其他進程饑餓(例如,沒有為專用伺服器留下足夠的空間來建立其PGA,甚至無法啟動)。這個其實是快取資料,也是為什麼你第二次進行同一個操作的時候比第一次要快的原因,因為他可以直接從這個緩衝裡面取就可以了!但是如果你第二天來繼續進行同一操作應該是比較慢的,因為在那個緩衝裡面已經沒有你要取的資料了!( 就是通常說的記憶體老化,也就是緩衝你資料的那塊記憶體被別人用了。這就是LRU演算法),為了使自己要的資料不那麼快老化。oracle把這塊記憶體劃分為三種類型:
預設池(default pool):所有段塊一般都在這個池中緩衝。這就是原先的緩衝區池(原來也只有一個緩衝區池)。
保持池(keep pool):按慣例,訪問相當頻繁的段會放在這個候選的緩衝區池中,如果把這些段放在預設緩衝區池中,儘管會頻繁訪問,但仍有可能因為其他段需要空間而老化(aging)。
回收池(recycle pool):按慣例,訪問很隨機的大段可以放在這個候選的緩衝區池中,這些塊會導致過量的緩衝區重新整理輸出,而且不會帶來任何好處,因為等你想要再用這個塊時,它可能已經老化退出了緩衝。要把這些段與預設池和保持池中的段分開,這樣就不會導致預設池和保持池中的塊老化而退出緩衝。
4、shared pool(共用池)
共用池就是Oracle緩衝一些“程式”資料的地方。在解析一個查詢時,解析得到的表示(representation)就緩衝在那裡。在完成解析整個查詢的任務之前, Oracle會搜尋共用池,看看這個工作是否已經完成。你啟動並執行PL/SQL代碼就在共用池中緩衝,所以下一次運行時,Oracle不會再次從磁碟重新讀取。PL/SQL代碼不僅在這裡緩衝,還會在這裡共用。如果有1 000個會話都在執行同樣的代碼,那麼只會載入這個代碼的一個副本,並由所有會話共用。Oracle把系統參數儲存在共用池中。資料字典緩衝(關於資料庫物件的已緩衝資訊)也儲存在這裡。簡單地講,就像是廚房的水池一樣,什麼東西都往共用池裡放。我的理解是:這是個共用的東西,大家都可以用。比如一個使用者進行一次查詢,在解析之前,查看共用池,這個sql語句是否已經緩衝在這裡了。如果在,他就沒有必要再去進行解析了,因為已經解析好了,直接拿來用就可以了!這也是綁定變數為什麼可以改善oracle效能的原因!
5、large pool 大池
大池(large pool)並不是因為它是一個“大”結構才這樣取名(不過,它可能確實很大)。之所以稱之為大池,是因為它用於大塊記憶體的分配,共用池不會處理這麼大的記憶體塊。
在Oracle 8.0引入大池之前,所有記憶體配置都在共用池中進行。如果你使用的特性要利用“大塊的”記憶體配置(如共用伺服器UGA記憶體配置),倘若都在共用池中分配就不太好。另外,與共用池管理記憶體的方式相比,處理(需要大量記憶體配置)會以不同的方式使用記憶體,所以這個問題變得更加複雜。共用池根據LRU來管理記憶體,這對於緩衝和重用資料很合適。不過,大塊記憶體配置則是得到一塊記憶體後加以使用,然後就到此為止,沒有必要緩衝這個記憶體。我的理解是:其實是把原來屬於共用池裡面的一些特殊的記憶體拿出來進行不同的處理。因為這些記憶體用完之後就可以立即釋放,而共用池的記憶體不存在釋放問題,因為是大家共用的。
大池專門用於以下情況:
共用伺服器串連,用於在SGA中分配UGA區,因為一個使用者斷開之後,UGA就可以立即釋放!
語句的並存執行,允許分配進程間的訊息緩衝區,這些緩衝區用於協調並行查詢服務器。一旦發送了緩衝訊息就可以立即釋放!
備份,在某些情況下用於RMAN磁碟I/O 緩衝區。因為寫入磁碟之後,這些緩衝可以立即釋放!
6、Java pool Java池
在資料庫中運行Java代碼時用到這部分記憶體。例如:編寫Java預存程序在伺服器內運行。需要注意的是,該記憶體與常見的Java編寫的B/S系統並沒關係。用JAVA語言代替PL/SQL語言在資料庫中寫預存程序才會用到這部分記憶體。
7、Stream pool 流池
9iR2以上增加了“流”技術,10g以上在SGA中增加了流池。流是用來共用和複製資料的工具。
SGA設定
沒有通用的設定,所有設定都要根據系統的負載、業務需求和硬體環境來進行調整。這裡只是總結出大體的設定,避免因SGA設定不當引起的問題。
1、自動SGA記憶體管理
在Oracle 10g中引入了自動SGA記憶體管理特性,DBA可以設定SGA_TARGET告訴Oracle可用的SGA記憶體為多大,由Oracle根據系統負載來動態調整各組件大小,相應的數定會儲存在控制檔案中,使資料庫重啟後也記得各組件大小。
需要注意一下幾點:
? 要使用自動SGA記憶體管理,STATISTICS_LEVEL參數必須設為TYPICAL或ALL,系統自動收集相應的資訊用來動態調整SGA設定。
? 可以設定某個組件的值,Oracle使用此值為該組件的最小大小。
可動態調整的參數:
DB_CACHE_SIZE,SHARED_POOL_SIZE,LARGE_POOL_SIZE,JAVA_POOL_SIZE。
需手動設定的參數:
LOG_BUFFER,STREAMS_POOL,DB_NK_CACHE_SIZE,DB_KEEP_CACHE_SIZE,DB_RECYCLE_CACHE_SIZE。
2、手動SGA記憶體管理
1) 32bit和64bit限制
在32位的作業系統中,Oracle最大可用記憶體為1.75g,也就是說SGA+PGA<=1.75g,超過這一限制的記憶體將不會被Oracle用到。
32位的Oracle可以裝到64位的作業系統上,64位的Oracle不可以裝到32位的作業系統上。
2) 查看Oracle版本:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
3) 各組件設定:
JAVA_POOL_SIZE:如果沒用到資料庫端java的系統,30MB足夠。
LOG_BUFFER:預設為MAX(512KB,128KB*CPU個數)。一般系統1MB足夠,運行大型事務的系統可以設為2MB,讓1/3滿寫入記錄檔時可以繼續寫入緩衝,再大也沒有意義。
SHARED_POOL_SIZE:過大過小都會嚴重影響系統效能,1GB記憶體可以設為100MB,2GB記憶體可設為150MB,4GB記憶體可設為300MB。共用池命中過低首先要調整的是應用程式而不是擴大共用池。使用綁定變數可以減少共用池需求、提高命中率,減少共用池管理負擔和LATCH競爭。
LARGE_POOL_SIZE:使用專用服務模式可設為30MB,除非必要,不然不建議使用共用伺服器模式。
DB_CACHE_SIZE:除去上述記憶體外其他可用記憶體都分配給該地區。
總結
32位Oracle:
1G記憶體:SHARED_POOL_SIZE=100MB,DB_CACHE_SIZE=0.5GB;
2G記憶體:SHARED_POOL_SIZE=150MB,DB_CACHE_SIZE=1.25GB;
64位Oracle
4G記憶體:SHARED_POOL_SIZE=200MB,DB_CACHE_SIZE=2.5GB;
8G記憶體:SHARED_POOL_SIZE=400MB,DB_CACHE_SIZE=5GB;
12G記憶體:SHARED_POOL_SIZE=500MB,DB_CACHE_SIZE=8GB
再次強調,以上只是避免因SGA設定不當引起問題的大體設定,需要根據具體的系統負載和商務邏輯結合Stackpack等工具細調。
oracle SGA詳解