2014年12月1日 星期一

共享記憶體(System Global Area;SGA)

之所以稱為共享記憶體(System Global Area;SGA),是因為它可以被Oracle所在的作業系統上所有的使用者連線和程序來共用其中的資料,SGA幾個基本的特性依序如下:
  • SGA是由系統的記憶體所構成的裡面儲存了資料、使用者資訊和控制資訊。
  • 一個SGA只能服務於一個Instance,也就是說,當一台伺服器上有多個Instance運作時,每個Instance都有一個自己專屬的SGA,雖然同一台伺服器上SGA都是來自於作業系統上的記憶體,但Instance之間不能相互交流對方的SGA。
  • SGA是共用的,當有多個使用者連線到了這個Instance,SGA中的資訊可以同時被所有使用者同時使用,當然這牽涉了鎖定等等問題。
  • Oracle Process和一個SGA就可以構成了一個Oracle Instance。當Instance啟動時,Oracle會自動從作業系統中分配設定好的記憶體給SGA,而當Instance關閉時,作業系統會回收這些記憶體。下面就是當Instance啟動後,顯示已經分配了SGA的架構。

SGA記憶體分配圖
 
Tip-由上面的圖例可以看出,當Instance被開啟時,Oracle會自動按照參數檔(Parameter File)的設定,從系統的記憶體內分配適當的記憶體給SGA,由上而下所顯示的訊息如下: 
  • Total System Global Area:此訊息顯示目前此SGA的大小。  
  • Fixed Size:裡面儲存了SGA 各部分元件的相關資訊,主要是作為導引SGA架構的區域,當Instance被開啟時此塊區域就被固定住了不能做任何的變動,此塊區域也可稱為Fixed SGA。  
  • Variable Size:此資訊顯示Shared Pool、Java Pool、Large Pool和Streams Pool等的配置總和,由於這些記憶體區塊都是可動態分配的所以統稱Variable Size  
  • Database Buffers:此訊息顯示資料庫緩衝快取區的大小。  
  • Redo Log Buffers:此訊息顯示重作日誌緩衝區的大小。
        共享記憶體的設定是否完善與否,攸關整個Oracle資料庫的運行是否順暢,因此SGA的參數設定與相關視觀表解析是不容忽視的,下面將深入介紹這些元件的功用、重要觀念、參數與相關視觀表解析。SGA的組成包含數個重要的區域,分別為:
 
  • 資料庫緩衝快取區(Database Buffer Cache)
  • 重作日誌緩衝區(Redo Log Buffer)
  • 共用區(Shared Pool)
  • 與Java區(Java Pool)
  • 大型區(Large pool)
  • 串流區(Stream Pool)
  • 固定SGA(Fix SGA)

 共享記憶體的重要觀念

  • 一般來說當DBA安裝Oracle軟體時,針對作業系統首先會先辨別是32-Bit還是64-Bit,而這32-Bit和64-Bit又是代表什麼意思,簡單來說就是CPU對於記憶體的定址大小,也就是說CPU對於記憶體最大的支援範圍,舉一個例子在CPU的世界裡,所有一切都是以二進位表示,一個32-Bit的CPU對於記憶體搜尋的範圍就是2的32次方也就是等於4G的大小,但有時伺服器的實際實體記憶體沒有這麼大,假設說只有2G但軟體的應用是根本不考慮實際實體記憶體多大,還是按照32-Bit的方向來規劃,也就是4G的記憶體來分配,為了擬補實體記憶體的不足,作業系統就有了虛擬記憶體的概念,如果當所定址的資料實際上不在實體記憶體中,那就從虛擬記憶體中來補足,而這個虛擬記憶體是從硬碟上劃分的一塊專門的區域,例如在Linux和Unix下的SWAP而在Windows作業系統上是pagefile.sys,而實體記憶體與虛擬記憶體之間的交換是由作業系統來控制,所以說虛擬記憶體的一個好處就是可以使Process使用到很大的虛擬記憶體,而無需考慮實際的實體記憶體的大小,並讓使用者感覺實體記憶體變大了,可是如果由實體記憶體持續的不足,因此必須時常將實體記憶體內的東西Page Out到磁碟空間上,此時會嚴重影響到系統的效能因為從磁碟空間上讀取資料會比讀取實體記憶體慢上14000倍。
  • Oracle對於記憶體的管理主要是透過兩個記憶體管理模組,分別是Kernel Service Memory簡稱KSM和Kernel Generic Heap簡稱KGH,而記憶體管理模組是負責與作業系統進行介面以獲取用於Oracle的記憶體,同時還負責靜態記憶體的分配。Kernel Generic Heap主要負責Shared Pool、Library cache和PGA的記憶體分配,Kernel Service Memory主要負責記錄 Fix SGA、Database Buffer Cache和Log Buffer Cache的記憶體分配,可由X$KSMFS(Kernel Services Memory Fixed SGA )此Oracle內部表格查看相關訊息,如下圖
X$KSMFS

共享記憶體的重要參數

SGA_MAX_SIZE

           共享記憶體(System Global Area;SGA)裡面包含了Oracle資料庫裡面最核心的緩衝區與各種記憶體區塊,而這些緩衝區與記憶體區塊絕大部分都可以透過參數檔(Parameter File)裡面的特定參數來指定他們的大小,但是系統的資源多寡是有限制的如記憶體和CPU等等,如果設定不當勢必影響到系統與資料庫運作的效能,舉一個例子,如果Oracle資料庫的SGA設定的太小會導致頻繁I/O或是使用到硬碟上的空間來作為虛擬的記憶體,如此一來會大大影響資料庫的性能,但如果Oracle資料庫的SGA設定的太大會影響到作業系統的效能,由此可知設定SGA的大小是相當重要的課題,設定的是否完善可能影響到資料庫的效能,甚至可能會導致系統損毀。所以在Oracle資料庫裡面有一個參數來控制SGA使用虛擬記憶體的最大大小,這個參數就是SGA_MAX_SIZE。
       當Instance開啟後,各個記憶體區會依照最少的需求,分配所需要的大小,在隨後的Oracle運作的過程中,再根據實際上的需要擴展SGA裡面各區塊的大小,但SGA內的各區塊的總和大小是受到了SGA_MAX_SIZE的限制與參數檔內每個區塊的設定,如果試圖手動增加記憶體區塊的大小,導致整體記憶體區大小總和大於SGA_MAX_SIZE的設定時,Oracle將會產生錯誤訊息,如圖所示。

SGA_MAX_SIZE的限制
        一般來說對於線上交易的系統(On-Line Transaction Processing system;OLTP)SGA的大小建議可以如下配置SGA_MAX_SIZE,如下所示。
  • 系統記憶體 1G 時SGA_MAX_SIZE建議為500M
  • 系統記憶體 2G 時SGA_MAX_SIZE建議為1G
  • 系統記憶體 4G 時SGA_MAX_SIZE建議為2.5G
  • 系統記憶體 8G 時SGA_MAX_SIZE建議為5G
  • 系統記憶體 16G 時SGA_MAX_SIZE建議為10G
Tip-SGA的大小設置,需要經過觀察與調整才能設定成最完美的狀態
 

SGA_TARGET

        SGA_TARGET是在Oracle10g中引進的一個非常重要的參數。在Oracle 10g之前,SGA的各個記憶體區塊的大小都必須在參數檔內設定,一但設定後各個記憶體區塊的大小都無法超出次設定的範圍,儘管所有記憶體區塊的大小總合沒有超過SGA_MAX_SZIE的設定,除此之外,一旦Oracle將各個記憶體區塊分配完後,各個記憶體區塊相互之間是不能共用的,因此有時就會發生魚與熊掌不可兼得的情況,舉一個實際的例子,Database Buffer Cache和Shared Pool是對個對整個Instance的效能影響最大的兩個記憶體區塊,當系統記憶體資源有限的情況下,某些時候資料被cache的需求量會非常大以減少I/O的次數,所以為了提高buffer hit,就需要增加Database Buffer Cache的大小,但由於SGA與作業系統的記憶體有限,所以只能從其他記憶體區塊分一些空間來加大Database Buffer Cache,例如縮小Shared Pool的大小,但如果此時又有大塊的PLSQL需要被到入記憶體中,此時又會導致Shared Pool不足,甚至出現ORA-4031錯誤,此時又需要擴大Shared Pool的大小,所以可能又必需從Database Buffer Cache中將記憶體在分一點回來,所以為瞭解決這種矛盾的問題在Oracle 10g 時就產生了SGA_TARGE此參數,當設定這個參數後,就不需要指定每個記憶體區塊的大小了。SGA_TARGET指定了SGA可以使用的最大記憶體大小,而SGA中各個記憶體區塊的大小由Oracle自行控制,不需要人為指定。Oracle可以隨時調節各個區域的大小,使之達到系統性能最佳狀態。
       SGA_TARGET是利用自動共享記憶體管理(Automatic Shared Memory Management ASMM)來做控制的,一旦給SGA_TARGET指定值後(預設值為0,即沒有啟動ASMM)如圖所示,就自動啟動了ASMM特性。當設定了SGA_TARGET的值之後,以下的SGA記憶體區塊就可以由ASMM來自動調整:
  • 資料庫緩衝快取區(Database Buffer Cache)
  • 共用區(Shared Pool)
  • 與Java區(Java Pool)
  • 大型區(Large pool)
  • 串流區(Stream Pool)
SGA_TARGET預設值如圖

SGA_TARGET預設值
 如使用PL/SQL手動設定SGA_TARGET的語法如下,設定完後須重啟資料庫


設定SGA_TARGET

LOCK_SGA

為了保證SGA都被鎖定在實體記憶體中,而不必Page In/Out,可以透過LOCK_SGA此參數來控制,LOCK_SGA預設值為FALSE,當指定為TRUE時,可以將全部SGA都鎖定在實體記憶體中。設定的語法如下。
SQL> ALTER SYSTEM SET LOCK_SGA=true SCOPE=SPFILE;

TIP - LOCK_SGA注意事項
  • LOCK_SGA此參數是無法動態修改所以必須先以ALTER SYSTEM…的語法寫到SPFILE中,或是直接修改PFILE,之後再重啟Instance,LOCK_SGA的新值才會生效。 
  • 有些作業系統不支援記憶體鎖定,因此這參數也就無效。

PRE_PAGE_SGA

前面有提到,當Instance啟動時,並不會將SGA內所有的設定大小全部載入到作業系統的記憶體內,只會告訴作業系統Oracle會有這麼多的空間要使用,所這些記憶體空間我先預約了,而一開始真正載入的只會是各個記憶體區塊最小的大小,而其他SGA記憶體只作為虛擬記憶體分配,只有當程式到達到相應的點時,才會置換到實體記憶體中,但PRE_PAGE_SGA的設定可以將以上的動作省略,也就是說當Oracle Instance一啟動時就將所有SGA都分配到實體記憶體。PRE_PAGE_SGA的預設值為FALSE,也就是不將全部SGA載入到實體記憶體中,當設定為TRUE時,Oracle Instance啟動時會將全部SGA載入到實體記憶體中。設定的語法如下。
SQL> ALTER SYSTEM SET PRE_PAGE_SGA=true SCOPE=SPFILE;
TIP-注意事項 
  • PRE_PAGE_SGA此參數是無法動態修改所以必須先以ALTER SYSTEM…的語法寫到SPFILE中,或是直接修改PFILE,之後再重啟Instance,PRE_PAGE_SGA的值才會生效。 
  • PRE_PAGE_SGA可以使Instance一啟動後就達到設定時的最佳性能狀態,但是Instance啟動的時間也會更長,因為要將使所有SGA都載入到實體記憶體中 
  • PRE_PAGA_SGA只是在Instance啟動時將實體記憶體分配給SGA,但並意味著系統在以後的運作的過程不會將SGA中的某些Page置換到虛擬記憶體中,也就是說儘管設置了這個參數,還是可能出現Page In/Out的狀況。如果需要保障SGA不被Page In/Out,就需要使用另外一個參數LOCK_SGA來控制了。


共享記憶體的重要視觀表

V$SGA

V$SGA此視觀表顯示SGA的概況,所提供的資訊和SHOW SGA一模一樣,如下圖所示。

V$SGA
 
TIP-V$SGA
  • Fixed Size:裡面儲存了SGA 各部分元件的相關資訊,主要是作為導引SGA架構的區域,當Instance被開啟時此塊區域就被固定住了不能做任何的變動,此塊區域也可稱為Fixed SGA。
  • Variable Size:此資訊顯示Shared Pool、Java Pool、Large Pool和Streams Pool等的配置總和,由於這些記憶體區塊都是可動態分配的所以統稱Variable Size
  • Database Buffers:此訊息顯示資料庫緩衝快取區的大小。
  • Redo Log Buffers:此訊息顯示重作日誌緩衝區的大小。

V$SGASTAT

V$SGASTAT主要是記錄了有關SGA的統計資訊,與記憶體分配的狀況,對於發生ORA-4031有很重要的參考價值。裡面的資訊是由三個欄位組成依序:Name(SGA記憶體區塊的名稱),Bytes(記憶體區塊的大小),Pool(記憶體所屬的記憶體區塊)。
以下的語法可查詢記憶體區塊還剩多少使用空間
   SELECT POOL, NAME, BYTES / 1024 / 1024 MB
    FROM V$SGASTAT WHERE NAME = 'FREE MEMORY';



Check Free Memory
以下的語法可查詢Shared Pool的使用狀況比率
  SELECT TO_NUMBER (V$PARAMETER.VALUE) VALUE,
         V$SGASTAT.BYTES/1024/1024 “V$SGASTAT MB”,
        (V$SGASTAT.BYTES/V$PARAMETER.VALUE) * 100 “PERCENT FREE”
  FROM V$SGASTAT, V$PARAMETER
  WHERE V$SGASTAT.NAME = ‘ free memory’
  AND V$PARAMETER.NAME = ‘shared_pool_size’
  AND V$SGASTAT.POOL = ‘shared pool’;

V$SGA_TARGET_ADVICE

當設定了SGA_TARGET參數後Oracle將會收集SGA相關的統計數據,並透過V$SGA_TARGET_ADVICE呈現出來,因此可以根據這些資SGA_TARGET做相關的調整,以達到最佳狀況,裡面欄位組成如下:
  • SGA_SZIE:資料庫緩衝快取區的名稱(Default、Keep、Recycle)
  • SGA_SIZE_FACTOR:SGA SZIE的估算因子
  • ESTD_DB_TIME:預估DB處理時間在目前的SGA大小
  • ESTD_DB_TIME_FACTOR:當SGA大小為SGA_SIZE時,將預估DB處理時間與實際DB處理時間的比例
  • ESTD_PHYSICAL_READS:當SGA大小為SGA_SIZE時,SGA預測得實體讀取數。
在此要注意,如果需要將資料收集到V$SGA_TARGET_ADVICE,除了要設定SGA_TARGET之外,還須確認STATISTICS_LEVEL此參數不能為'BASIC'。
確認參數STATISTICS_LEVEL是否為'typical'或是'all',在參數檔設定方式如下:
  statistics_level=ALL | TYPICAL | BASIC
動態設定方式可分為兩種,'ALTER SYSTEM'是對整個資料庫生效,'ALTER SESSION'是對當前使用的連線生效,語法範例如下:
  ALTER SYSTEM SET statistics_level=typical;
  ALTER SESSION SET statistics_level=typical;
確認statistics_level的狀態可使用一下方式
  SHOW PARAMETER statistics_level
使用V$SGA_TARGET_ADVICE的簡單查詢評估方式如下:
  SELECT * FROM V$SGA_TARGET_ADVICE ORDER BY SGA_SIZE_FACTOR;

查詢結果如下圖
V$SGA_TARGET_ADVICE
由上面的例子可以看出當SGA的SIZE是在800 MB到1G都是合理的範圍,當然如果系統記憶體夠大也可多設定一些空間,這裡要注意的是SGA_TARGET的限制是大小是不能超過SGA_MAX_SIZE的設定。

以上是Oracle SGA的基本介紹,希望對所有讀者在工作上有些許的幫助!!!



沒有留言 :

張貼留言