SlideShare a Scribd company logo
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
第三章 執行處理的記憶體管理
前言
Oracle 執行處理(Instance)雖說由系統整體區域(SGA)與背景處理作業(Background Process)
組成,但是主要影響效能的關鍵,多為系統整體區域的共用記憶體管理不當所造成。而系統
整體區域中最重要的共用記憶體元件為緩衝區快取(Buffer Cache)與共用集區(Shared Pool)。
因此本章特別更進一步說明系統整體區域的記憶體管理,以及緩衝區快取與共用集區的內容,
希望可以讓資料庫管理者真正了解系統整體區域的內涵。
3.1 記憶體管理
Oracle 伺服器所使用到的記憶體可分為兩種:系統整體區域(System Global Area-縮寫為
SGA)、程式整體區域(Program Global Area-縮寫為 PGA)。每個 Oracle 執行處理只有一個
SGA,放在 SGA 的資料可被所有的背景處理作業與伺服器處理作業(Server Process)所存取。
但是每個背景處理作業或伺服器處理作業各自有一個私有的記憶空間,稱作 PGA,放在 PGA
的資料只有背景處理作業或伺服器處理作業自己才能存取。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
在整個執行處理的管理工作中,以 SGA 的設定與管理最為複雜。因為 SGA 是由許多共用記
憶體元件組成,常見的有共用集區-Shared Pool、緩衝區快取-Buffer Cache、重做日誌緩衝
區-Redo Log Buffer、大型集區-Large Pool、Java 集區-Java Pool、串流集區-Streams
Pool 等。然而不同型態的 SQL 敘述句使用到的共用記憶體元件也有所不同,因此共用記憶
體元件需要隨時著資料庫的不同狀況而調整,才能得到最佳的系統效能。也因為如此資料庫
管理者得時時盯著資料庫,適時地調整共用記憶體元件的大小,才能讓 Oracle 伺服器的效能
達到最佳。但這樣的監控方式對資料庫管理者來說,無疑是相當大的負擔。雖然從 Oracle
Database 9i 開始,資料庫管理者可以在不關閉執行處理的狀態下,動態地調整某些共用記憶
體元件的大小,可是共用記憶體元件的大小還是需要人為調整。
不過 Oracle Database 10g 開始,資料庫管理者可以藉由自動共用記憶體管理(Automatic
Shared Memory Management-縮寫為 ASMM),讓執行處理自動依據 Oracle 伺服器狀況,
將共用記憶體分配給目前最需要的元件。這個功能一方面可以減輕資料庫管理者的負擔,另
一方面也可以減少 ORA-4031 記憶體不足的錯誤發生。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3.1.1 自動記憶體管理(Automatic Memory Management)
Oracle Database 11g 的自動記憶體管理(Automatic Memory Management-縮寫為 AMM)讓
資料庫管理者只需指定整個 Oracle 伺服器所能使用的最大記憶體空間,不需個別設定 SGA
或 PGA 的大小,之後 Oracle 執行處理自動依 Oracle 伺服器狀態調整 SGA 與 PGA 的大小,
以及 SGA 的其他共用記憶體元件的大小(緩衝區快取、共用集區、大型集區、Java 集區、
Streams 集區)。
當執行處理剛啓動時,SGA 佔記憶體目標的 60%,而 PGA 佔 40%,之後隨著 Oracle 伺服
器狀態,由背景處理作業 Memory Management(MMAN)動態地調整兩者的比率以達到
Oracle 伺服器的最佳效能。資料庫管理者如果想要啓用(Enable)自動記憶體管理機制,可以
藉由設定 MEMORY_MAX_TARGET 與 MEMORY_TARGET 這兩個參數來啟動。需要注意的
事為 MEMORY_TARGET 必須小於 MEMORY_MAX_TARGET。
啟動自動記憶體管理
1.取得 SYSDBA 的權限。
在 SQL*PLUS 環境下執行”SHOW USER”指令,出現的使用者若為 SYS 即表示此階段作
業已經取得 SYSDBA 權限。因為從 Oracle Database 9i 開始,使用者 SYS 只能使用
SYSDBA 或 SYSOPER 身分登入。
[ora11g@elinux5 ~]$ export $ORACLE_SID=ora11g /*設定執行處理的名字*/
[ora11g@elinux5 ~]$ sqlplus / AS SYSDBA /*以OS驗證,取得SYSDBA權限*/
SQL> SHOW USER
USER is “SYS”
2.是否啓用自動記憶體管理。執行”SHOW PARAMETER target”來查看,若
MEMORY_TARGET 值為 0,表示尚未啓動自動記憶體管理。若 MEMORY_TARGET 值大於
0,則表示已經使用自動記憶體管理。
SQL> SHOW PARAMETER target
NAME TYPE VALUE
------------------------------------------ ---------------- ------------------------------
memory_max_target big integer 0 --記憶體最大目標
memory_target big integer 0 --記憶體目標
pga_aggregate_target big integer 100M --PGA聚總目標
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
sga_target big integer 304M --SGA目標
3.計算所需要的記憶體總大小。將 SGA 目標(SGA_TARGET)與 PGA 聚總目標
(PGA_AGGREGATE_TARGET)相加即可,不過因為 PGA 聚總目標是軟限制(soft limit),實
際使用的 PGA 總空間可能超過 PGA 聚總目標。所以要找出目前 Oracle 伺服器曾經使用到的
PGA 最大值,與 PGA 聚總目標比較,取兩者之中較大的值為代表。之後將所得的 PGA 使用
值與 SGA 目標相加,這樣所得到的結果才能符合目前 Oracle 伺服器的需求。
SQL> SELECT value FROM v$pgastat
2> WHERE name='maximum PGA allocated'; --曾經使用過的最大PGA值
VALUE
----------------
244552704
依照範例來看,目前 Oracle 伺服器中 PGA 空間最大曾經用到 233M,較 PGA 聚總目標
(100M)來得大。所以記憶體目標(MEMORY_TARGET)應該設為 537M(233M+304M)。
4.設定 MEMORY_TARGET 與 MEMORY_MAX_TARGET。MEMORY_MAX_TARGET 是用
來設定 Oracle Servery 最大可使用多少的記憶體,MEMORY_MAX_TARGET≧
MEMORY_TARGET。通常管理者只需要設定 MEMORY_TARGET 即可,因為
MEMORY_MAX_TARGET 的值預設與 MEMORY_TARGET 一樣。若設定
MEMORY_MAX_TARGET 而且大於 MEMORY_TARGET,則主要是用在尋找最適當的
MEMORY_TARGET 時,可以讓 MEMORY_TARGET 及時增加空間,而不需要重新啓動
Oracle Instance。
SQL> ALTER SYSTEM SET memory_target=537M SCOPE=SPFILE;
/*不能直接修改memory_target的原因,是memory_target必須小於或等於memory_max_targe
t,而現在memory_max_target為0,且memory_max_target不能動態改變。*/
SQL> ALTER SYSTEM SET sga_target=0;
SQL> ALTER SYSTEM SET pga_aggregate_target=0;
--重新啟動執行處理,讓memory_target設定生效
SQL> SHUTDOWN IMMEDIATE
SQL> STARTUP
SQL> SHOW PARAMETER target
NAME TYPE VALUE
------------------------------------------ ----------------------- ----------
memory_max_target big integer 544M
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
memory_target big integer 544M
pga_aggregate_target big integer 0
sga_target big integer 0
/*出現的不是537M,而是544M.因為MEMORY_TARGET要為Granule的整數倍,目前的Granule s
ize為4M.*/
但是目前 MEMORY_TARGET 設定為 544M 到底夠不夠用?管理者可已由 V$
MEMORY_TARGET_ADVICE 得知,若加大 MEMORY_TARGET 的值是否有好處?反之若
減少 MEMORY_TARGET 的值是否影響整體的效能?
SQL> SELECT memory_size,memory_size_factor size_factor,
2> estd_db_time db_time,estd_db_time_factor db_time_factor
3> FROM v$memory_target_advice;
MEMORY_SIZE SIZE_FACTOR DB_TIME DB_TIME_FACTOR
---------------------- ----------------------- -------------------- --------------------------
544 1 443 1
272 .5 444 1
408 .75 444 1
680 1.25 444 1
816 1.5 443 .9983
952 1.75 443 .9983
1088 2 443 .9983
--將記憶體目標設定為272M
SQL> ALTER SYSTEM SET memory_target=272M;
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
由上面的範例可以看到目前的 MEMORY_TARGET 為 544M,因為
MEMORY_SIZE_FACTOR 為 1。同時可以得知,即使將 MEMORY_TARGET 增加為 816M,
可以減少一些 DB_TIME,但是差距實在太小,以比率而言也只有 0.0017。這時資料庫管理
者便不應該將 SGA_TARGET 設為 816M,因為只有浪費記憶體而已。如果資料庫管理者這
時將 MEMORY_TARGET 設為 272M,DB_TIME 沒有明顯的增加,而 Oracle 伺服器所佔用
的記憶體卻可以大幅下降,而節省下來的記憶體空間可以給作業系統的其他服務使用,這些
其他服務當然也包含其他的 Oracle 伺服器。那麼資料庫管理者何樂不為呢?那為何不選擇
408M 呢?因為 MEMORY_TARGET 設為 408M,得到]DB_TIME 卻與設為 272M 相同,這
樣只有浪費不必要的記憶體,並沒有其他的好處。所以依範例的結果來看,
MEMORY_TARGET 降為 272M 是最好的選擇。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
資料庫管理者也可以透過資料庫控制(Database Control)或網格控制(Grid Control)的管理界
面,使用記憶體建議(Memory Advisor)程式得到相關的訊息。
當啟用自動記憶體管理後,資料庫管理者可由 V$MEMORY_DYNAMIC_COMPONENTS,得
到目前共用記憶體元件的大小以及可以那些共用記憶體元件可以動態地變更大小。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
雖然使用自動記憶體管理時,Oracle 伺服器可以自動管理一些共用記憶體元件的大小,但不
是每個共用記憶體元件的大小都可以被自動管理。資料庫管理者可以由 V$SGA_INFO 得知目
前共用記憶體元件的大小及哪些共用記憶體元件的大小可以自動管理。如果 RESIZEABLE 為
YES,表示這個共用記憶體元件的大小可以被 Oracle 執行處理自動管理。
◎Oracle11g:SHARED POOL、LARGE POOL、JAVA POOL、STREAMS POOL、
DEFAULT BUFFER CACHE、SHARED IO POOL。注意:雖然 PGA 的空間也可以被自動
管理,但不會出現在下面的範例中,因為 PGA 不是共享記憶體的一部份。
SGA 是由多個不同用途的共用記憶體元件所組成,但不是每個共用記憶體元件都可以被自動
管理。有些共用記憶體元件從執行處理啓動後,便不能變更其大小。例如:固定 SGA(Fixed
SGA)、日誌緩衝(Log Buffer)、結果集快取(Result Cache)。而有些元件的大小雖然可以動
態改變,但必須由資料庫管理者自行變更,而不能由 Oracle 執行處理自動管理。例如:保存
緩衝快取(KEEP BUFFER CACHE)、回收緩衝快取(RECYCLE BUFFER CACHE)、預設
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
2K 緩衝快取(DEFAULT 2K BUFFER CACHE)、預設 4K 緩衝快取(DEFAULT 4K BUFFER
CACHE)、預設 8K 緩衝快取(DEFAULT 8K BUFFER CACHE)、預設 16K 緩衝快取
(DEFAULT 16K BUFFER CACHE)、預設 32K 緩衝快取(DEFAULT 32K BUFFER
CACHE)、自動儲存管理緩衝快取(ASM BUFFER CACHE)。
因此使用自動記憶體管理時,MMAN 會先扣除不能被自動管理的記憶體空間後,然後才將剩
餘的共用記憶體空間依照 Oracle 伺服器的狀況,將共用記憶體分配給共用集區(SHARED
POOL)、大型集區(LARGE POOL)、JAVA 集區(JAVA POOL)、STREAMS 集區
(STREAMS POOL)、預設緩衝快取(DEFAULT BUFFER CACHE)、共用 IO 集區(SHARED
IO POOL)及 PGA 目標(PGA TARGET)。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3.1.2 自動共用記憶體管理(Automatic Shared Memory
Management)
在 Oracle Database10g 的時代,雖然沒有自動記憶體管理的功能,但是資料庫管理者可以
使用自動共用記憶體管理(Automatic Shared Memory Management-縮寫為 ASMM)的功能,
讓資料庫管理者僅需設定 SGA 總大小(SGA_TARGET)的值即可,其餘共用記憶體元件的大
小則自動依 Oracle 伺服器狀態自動決定,而且還可以動態地調整共用記憶體元件的大小。
至於自動記憶體管理與自動共用記憶體管理的差異,則在於自動記憶體管理可以同時自動管
理 SGA 與 PGA 的大小。而自動共用記憶體管理只能自動管理 SGA 的大小,不能管理 PGA
的大小。不過自 Oracle Database 9i 開始,資料庫管理者可以藉由設定 PGA 聚總目標
(PGA_AGGREGATE_TARGET)讓 PGA 的管理機制變成自動管理。所以在 Oracle Database
10g 只要啟用(Enable)自動共用記憶體管理與設定 PGA 聚總目標,便可以達到類似 Oracle
Database 11g 自動記憶體管理的效果。
啟用自動共用記憶體管理,只需將 SGA_TARGET 的值設為大於 0 即可 。資料庫管理者可以
透過下列的步驟,啟用自動共用記憶體管理:
1.取得 SYSDBA 的權限。
2.如果是 Oracle Database 11g,需要先停用(Disable)自動記憶體管理。
SQL> SHOW PARAMETER target
NAME TYPE VALUE
------------------------------------------ ---------------- ------------------------------
memory_max_target big integer 544M
memory_target big integer 544M
pga_aggregate_target big integer 0
sga_target big integer 0
SQL> ALTER SYSTEM SET memory_target=0; --停用自動記憶體管理
SQL> SHOW PARAMETER target
NAME TYPE VALUE
------------------------------------------ ----------------------- ----------------------------
pga_aggregate_target big integer 0
sga_target big integer 0
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
SQL> SHOW PARAMETER pool_size
NAME TYPE VALUE
------------------------------------------ ----------------------- --------------------------
java_pool_size big integer 24M
large_pool_size big integer 0
shared_pool_size big integer 64M
streams_pool_size big integer 0
SQL> SHOW PARAMETER cache_size
NAME TYPE VALUE
------------------------------------------ ---------------------- ---------------------------
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 48M
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
由以上範例可以得知目前自動共用記憶體管理的功能是停用,因為 SGA_TARGET 的值為 0。
而 SHARED POOL 與 JAVA POOL、DEFAULT BUFFER CACHE 的值為記載於參數檔的
設定。
3.設定 SGA_TARGET 為適當值。
SQL> SHOW PARAMETER sga
NAME TYPE VALUE
---------------------------------------- ------------------------- -----------------
sga_max_size big integer 544M
sga_target big integer 0
/*啟用自動共用記憶體管理時,注意sga_target必須小於等於sga_max_size
若sga_max_size為0,則需要先設定sga_max_size參數,才能設定sga_target參數。可是sga_
max_size為靜態參數,必須使用下面的指令才能設定。
ALTER SYSTEM SET sga_max_size=544M SCOPE=spfile。
並且重新啟動Oracle執行處理,才能生效。*/
SQL> ALTER SYSTEM SET sga_target=300M;
SQL> SHOW PARAMETER sga
NAME TYPE VALUE
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
---------------------------------------- ------------------------- -----------------
sga_max_size big integer 544M
sga_target big integer 300M
SQL> SHOW PARAMETER pool_size
NAME TYPE VALUE
---------------------------------------- ------------------------ -----------------
java_pool_size big integer 0
large_pool_size big integer 0
shared_pool_size big integer 0
streams_pool_size big integer 0
SQL> SHOW PARAMETER cache_size
NAME TYPE VALUE
---------------------------------------- ------------------ -----------------
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
由上面的範例結果來看,可以看到 SGA_TARGET 為 300M,而其他組成 SGA 的共用記憶體
元件都沒有明確設定其大小,則那些共用記憶體元件的大小則由 Oracle 伺服器依整體的狀態
來決定。
但是目前 SGA_TARGET 設定為 300M 到底夠不夠用?管理者可已由 V$
SGA_TARGET_ADVICE 得知,若加大 SGA_TARGET 的值是否有好處?反之若減少
SGA_TARGET 的值是否影響整體的效能?
SQL> SELECT sga_size,sga_size_factor size_factor,
2> estd_db_time_factor time_factor,estd_physical_reads phy_reads
3> FROM v$sga_target_advice;
SGA_SIZE SIZE_FACTOR TIME_FACTOR PHY_READS
--------------------------- ------------------------ ------------------- ---------------------
300 1 1 12970
225 .75 1.0429 12970
375 1.25 1 12970
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
450 1.5 .7786 9604
525 1.75 .7786 9604
600 2 .7786 9604
--如果有足夠的Free Memory
SQL> SELECT * FROM v$sga_dynamic_free_memory;
CURRENT_SIZE
----------------------
255852544 --尚有244M的可用記憶體空間
SQL> ALTER SYSTEM SET sga_target=450M;
--如果目前的Free Memory不足
SQL> SELECT * FROM v$sga_dynamic_free_memory;
CURRENT_SIZE
----------------------
0
/*沒有多餘的可用記憶體,因此必須同步增加sga_max_size2的值,但是sga_max_size為靜態
參數,必須先設定到參數檔,等執行處理重新啟動後,才會生效。*/
SQL> ALTER SYSTEM SET sga_max_size=450M SCOPE=spfile;
SQL> ALTER SYSTEM SET sga_target=450M SCOPE=spfile;
--重新啟動執行處理,讓新的sga_max_size與sga_target設定生效
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
由上面的範例可以看到目前的 SGA_TARGET 為 300M,因為 SGA_SIZE_FACTOR 為 1。
同時可以得知,如果將 SGA_TARGET 增加為 450M,可以減少 3366 個實體讀取(由資料檔
將資料區塊讀到緩衝區快取的操作,這種型態的讀取數量越大,整體資料庫的效能越差,應
該盡量避免此種讀取型態)。這時資料庫管理者便可以考慮將 SGA_TARGET 設為 450M,以
減少實體讀取數量,進而提昇整體資料庫的效能。需要注意的地方是 SGA_TARGET 的值必
須小於 SGA_MAX_SIZE。
那為什麼不增加為 375M 或 600M 呢?首先增加到 375M 並沒有同步減少實體讀取量,這樣
只有浪費所增加的記憶體。然後增加為 600M 與增加到 450M 的效果一樣,那為何要多浪費
150M 的記憶體。所以依範例的結果來看,SGA_TARGET 增加為 450M 是最好的選擇。
如果資料庫管理者不想要直接查詢動態效能視觀圖(Dynamic Performance View),也可以透
過 EM(Enterprise Manager)的記憶體建議程式,得到相關的建議。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
如果資料庫管理者想要知道目前各個共用記憶體元件的大小,可以查詢
V$SGA_DYNAMIC_COMPONENTS 來得到相關資訊。
SQL> select component,current_size from v$sga_dynamic_components;
COMPONENT CURRENT_SIZE
------------------------------------------------------ ----------------------
shared pool 121634816
large pool 4194304
java pool 12582912
streams pool 0
DEFAULT buffer cache 171966464
KEEP buffer cache 0
RECYCLE buffer cache 0
DEFAULT 2K buffer cache 0
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
DEFAULT 4K buffer cache 0
DEFAULT 8K buffer cache 0
DEFAULT 16K buffer cache 0
DEFAULT 32K buffer cache 0
Shared IO Pool /*11g新增*/ 0
ASM Buffer Cache 0
在自動共用記憶體管理的機制下,Oracle 伺服器可以自動管理某些共用記憶體元件,但不是
所有的共用記憶體元件都可以被自動管理。資料庫管理者可由 V$SGA_INFO 中得知目前共用
記憶體元件的配置狀況及哪些共用記憶體元件可以自動管理。如果某個記憶體元件的
RESIZEABLE 欄位值為 YES,表示該共用記憶體元件可以自動管理。
◎Oracle11g:SHARED POOL、LARGE POOL、JAVA POOL、STREAMS POOL、
DEFAULT BUFFER CACHE、SHARED IO POOL。
◎Oracle10g:SHARED POOL、LARGE POOL、JAVA POOL、STREAMS POOL、
DEFAULT BUFFER CACHE。
SQL> SELECT * FROM v$sgainfo;
NAME BYTES RESIZE
------------------------------------------------------ ----------------------- ------------
Fixed SGA Size 129962 No
Redo Buffers 6373376 No
Buffer Cache Size 188743680 Yes
Shared Pool Size 104857600 Yes
Large Pool Size 4194304 Yes
Java Pool Size 12582912 Yes
Streams Pool Size 0 Yes
Shared IO Pool Size /*11g*/ 0 Yes
Granule Size 4194304 No
Maximum SGA Size 318054400 No
Startup overhead in Shared Pool 46137344 No
Free SGA Memory Available 0
系統整體區域(SGA)是由多種不同用途的共用記憶體元件所組成,不是每個共用記憶體元件都
可以自動管理,也有些共用記憶體元件自 Oracle 執行處理啓動後,便不能變更其空間的大小:
Fixed SGA、Log Buffer、Result Cache(Oracle11 新增)。也有些是可以動態變更其空間的
大小,但必須是由資料庫管理者變更:KEEP BUFFER CACHE、RECYCLE BUFFER
CACHE、DEFAULT 2K BUFFER CACHE、DEFAULT 4K BUFFER CACHE、DEFAULT
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
8K BUFFER CACHE、DEFAULT 16K BUFFER CACHE、DEFAULT 32K BUFFER
CACHE、ASM BUFFER CACHE。
因此當使用自動共用記憶體管理時,Oracle 伺服器會先扣除不能被自動管理的共用記憶體元
件後,將剩餘的共用記憶體空間依照目前 Oracle 伺服器的狀況,最適地將記憶體分配給
SHARED POOL、 LARGE POOL、JAVA POOL、STREAMS POOL、DEFAULT
BUFFER CACHE、SHARED IO POOL(Oracle 11g 新增)。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3.1.3 動態系統整體區域(Dynamic SGA)
在 Oracle Database 9i 之前,如果 Oracle 執行處理已經啓動, 資料庫管理者想要改變任何
一種共用記憶體元件的大小,只能先修改參數檔(Parameter file)內容,將相關記憶體元件的
大小設定為所希望的大小,之後必須等待機會將 Oracle 執行處理重新啟動,這樣才能修改共
用記憶體元件的大小。
不過從 Oracle Database 9i 開始,藉由設定 SGA_MAX_SIZE 讓 SGA 的最大值不能超過此
值,資料庫管理者便可以動態變更某些共用記憶體的大小,而不需要將 Oracle 執行處理重新
啓動,這種功能稱做動態系統整體區域(Dynamic SGA)。那麼 Oracle 是怎樣做到動態調整某
些共用記憶體元件的大小呢?答案是 Granule。
Granule 是 Oracle Database 9i 開始使用的共用記憶體配置的單位,這種記憶體管理的技巧,
是將共享記憶體空間先切分為ㄧ塊塊的 Granule,每個 Granule 的大小是一樣的。然後再依每
個共用記憶體元件所需的大小,分配足夠個數的 Granule 給該共用記憶體元件,而且每個共
用記憶體元件被配置的 Granule 個數,一定要是整數個。Granule 的大小,則與 Oracle 版本、
作業系統及 SGA_MAX_SIZE 的設定值有關。
Granule Size:4M。當 SGA_MAX_SIZE<=1G(10g 之後)/128M(9i)
Granule Size : 8M。當 SGA_MAX_SIZE>1G(10g 之後)/128M(9i) ,而且作業系統為
MicroSoft Windows 平台系列。
Granule Size : 16M。當 SGA_MAX_SIZE>1G(10g 之後)/128M(9i)。
不過需要注意的地方是動態 SGA 的功能僅表示共用記憶體空間可以動態變更大小,不代表
Oracle 伺服器能自動管理這些共用記憶體的大小。資料庫管理者可以藉由查詢
V$SGA_DYNAMIC_COMPONENTS 得知,哪些共用記憶體可以動態變更其大小及目前的大
小。
SQL> SELECT component,current_size,granule_size
2> FROM v$sga_dynamic_components;
COMPONENT CURRENT_SIZE GRANULE_SIZE
------------------------------------------ ----------------------- ----------------------
shared pool 121634816 4194304
large pool 4194304 4194304
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
java pool /*10g*/ 2582912 4194304
streams pool /*10g*/ 0 4194304
DEFAULT buffer cache 171966464 4194304
KEEP buffer cache 0 4194304
RECYCLE buffer cache 0 4194304
DEFAULT 2K buffer cache 0 4194304
DEFAULT 4K buffer cache 0 4194304
DEFAULT 8K buffer cache 0 4194304
DEFAULT 16K buffer cache 0 4194304
DEFAULT 32K buffer cache 0 4194304
Shared IO Pool /*11g*/ 0 4194304
ASM Buffer Cache /*10g*/ 0 4194304
既然不能由 Oracle 伺服器自動管理,那麼資料庫管理者必須自己管理。但是資料庫管理者可
以參考 Oracle 伺服器所提供的多種顧問(Advisor)建議,這些建議可由
V$SHARED_POOL_ADVICE、V$DB_CACHE_ADVICE、V$JAVA_POOL_ADVICE、
V$STREMS_POOL_ADVICE 查知。
SQL> SHOW PARAMETER statistics_level
NAME TYPE VALUE
------------------------------- ----------- ------------------------------
statistics_level string TYPICAL
/*若要啟動相關的顧問建議,則statistics_level的設定值,必須為typical或all。如果statistics_le
vel的設定值為basic,則Oracle伺服器不會提供相關的建議。*/
SQL> DESC v$shared_pool_advice
Name Null? Type
----------------------------------------------------------------- ----------- ----------------
SHARED_POOL_SIZE_FOR_ESTIMATE NUMBER
SHARED_POOL_SIZE_FACTOR NUMBER
ESTD_LC_SIZE NUMBER
ESTD_LC_MEMORY_OBJECTS NUMBER
ESTD_LC_TIME_SAVED NUMBER
ESTD_LC_TIME_SAVED_FACTOR NUMBER
ESTD_LC_LOAD_TIME NUMBER
ESTD_LC_LOAD_TIME_FACTOR NUMBER
ESTD_LC_MEMORY_OBJECT_HITS NUMBER
SQL> SELECT shared_pool_size_for_estimate estd_size,
2> shared_pool_size_factor size_factor,
3> estd_lc_time_saved time_saved,
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
4> estd_lc_time_saved_factor aved_factor
5> FROM v$shared_pool_advice;
ESTD_SIZE SIZE_FACTOR TIME_SAVED SAVED_FACTOR
------------------ ----------------------- ---------------------- -------------------------
60 1 3886 1
68 1.1333 3995 1.0280
76 1.2667 4230 1.0885
84 1.4 4908 1.2630
92 1.5333 5501 1.4156
100 1.6667 6230 1.6031
108 1.8 6230 1.6031
116 1.9333 6230 1.6031
124 2.0667 6230 1.6031
SQ> alter system set shared_pool_size=100M;
上面的範例是以 V$SHARED_POOL_ADVICE 為例子,可以得知目前的共用集區(Shared
Pool)為 60M,因為其的 SHARED_POOL_SIZE_FACTOR 值為 1。也可以得知,如果將共
用集區的大小增為 100M 時,Oracle 伺服器的解析時間可以減少約 40%左右。因此如果有多
餘的共用記憶體,可以考慮增加共用集區的大小。
SQL> desc v$db_cache_advice
Name Null? Type
----------------------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(20)
BLOCK_SIZE NUMBER
ADVICE_STATUS VARCHAR2(3)
SIZE_FOR_ESTIMATE NUMBER
SIZE_FACTOR NUMBER
BUFFERS_FOR_ESTIMATE NUMBER
ESTD_PHYSICAL_READ_FACTOR NUMBER
ESTD_PHYSICAL_READS NUMBER
ESTD_PHYSICAL_READ_TIME NUMBER
ESTD_PCT_OF_DB_TIME_FOR_READS NUMBER
ESTD_CLUSTER_READS NUMBER
ESTD_CLUSTER_READ_TIME NUMBER
SQL> SELECT size_for_estimate estd_size,size_factor size_factor,
2> estd_physical_read_factor estd_read_factor,
3> estd_physical_reads estd_reads
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
4> FROM v$db_cache_advice
5> WHERE name='DEFAULT';
ESTD_SIZE SIZE_FACTOR ESTD_READ_FACTOR ESTD_READS
------------------- ---------------------- -------------------------------- -------------------
16 .0889 1.4367 19020
32 .1778 1.224 16204
48 .2667 1.0928 14467
64 .3556 1 13239
80 .4444 1 13239
96 .5333 1 13239
112 .6222 1 13239
128 .7111 1 13239
144 .8 1 13239
160 .8889 1 13239
176 .9778 1 13239
180 1 1 13239
192 1.0667 1 13239
208 1.1556 1 13239
224 1.2444 1 13239
240 1.3333 1 13239
256 1.4222 1 13239
272 1.5111 1 13239
288 1.6 1 13239
304 1.6889 1 13239
320 1.7778 1 13239
SQL> ALTER SYSTEM SET db_cache_size=64M;
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
上面的範例是以 V$DB_CACHE_ADVICE 為例子,可以得知目前的預設緩衝區快取
(DEFAULT CACHE BUFFER)為 180M,因為它的 SIZE_FACTOR 值為 1。也可以得知,如
果將預設緩衝區快取減為 64M 時,實體讀取的次數並不會因此而增加。這時資料庫管理者可
以將預設緩衝區快取空間縮小,並將多餘的共用記憶體分配給更需要記憶體的元件使用。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3.1.4 自動程式整體區域管理(Automatic PGA Management)
在 Oracle Database 9i 之前,每個伺服器處理作業(Server Process)所使用的程式整體區域
(Program Global Area)大小是由以下 4 個參數值所決定:SORT_AREA_SIZE、
HASH_JOIN_SIZE、CREATE_BITMAP_AREA_SIZE、MERGE_BITMAP_AREA_SIZE。
SORT_AREA_SIZE: 當進行排序操作(Sort Operation)時,每個排序操作所能使用的最大記
憶體空間,若超過此設定值,則該排序操作將使用暫時區段進行磁碟排序。預設值為 64K。
HASH_AREA_SIZE:當進行雜湊結合(Hash Join)時,所能使用的最大記憶體空間。預設值
為 128K。
CREATE_BITMAP_AREA_SIZE:當建立位元組索引(Bitmap Index)時,可以使用的記憶體
空間。若此設定值越大,則建立位元組索引的動作就越快完成。預設值為 8M。
MERGE_BITMAP_AREA_SIZE:當兩個位元組索引進行比對時,所使用的記憶體空間。此設
定值越大,則所需的比對時間就越短。預設值為 1M。
一個伺服器處理作業所擁有的 PGA 空間往往會隨著時間而成長,因為當伺服器處理作業會要
求更大的 PGA 空間來進行某些 SQL 敘述句,但是當 SQL 敘述句執行完畢後,這個 PGA 的
空間便由伺服器處理作業擁有,即使現在伺服器處理作業已經不需要這麼大的 PGA 空間,這
個 PGA 空間也不會縮減,只有在伺服器處理作業結束後,才會將該 PGA 所使用的記憶體還
給作業系統。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
當 PGA_AGGREGATE_TARGET 為 0 時,表示 PGA 的大小為*_AREA_SIZE 所決定。
SQL> CONNECT / AS SYSDBA --以sys身份,執行下面的範例
SQL> SHOW PARAMETER pga_aggregate_target
NAME TYPE VALUE
------------------------------------------ ----------------------- ---------------------------
pga_aggregate_target big integer 0
--當pga_aggregate_target為0,則pga的大小由下面4個參數決定
SQL> SHOW PARAMETER area_size
NAME TYPE VALUE
------------------------------------------ ---------------------- -----------------------------
bitmap_merge_area_size integer 1048576
create_bitmap_area_size integer 8388608
hash_area_size integer 131072
sort_area_size integer 65536
workarea_size_policy string MANUAL
--找出目前階段作業所使用的PGA大小
SQL> SELECT a.name,b.value
2> FROM v$statname a,v$sesstat b
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3> WHERE a.statistic#=b.statistic#
4> AND (a.name LIKE 'session%ga memory%%' OR a.name LIKE '%direct temp%')
5> AND sid=(SELECT distinct sid FROM v$mystat);
NAME VALUE
------------------------------------------------------------------ ----------
session uga memory 170876
session uga memory max 236340
session pga memory 473472 --目前使用量
session pga memory max 539008 --最大值
physical reads direct temporary tablespace 0
physical writes direct temporary tablespace 0
-- 建立一個測試表格
SQL> CREATE TABLE t1 AS SELECT * FROM dba_objects;
--收集表格的統計資料
SQL> EXECUTE DBMS_STATS.GATHER_TABLE_STATS(‘SYS’,’T1’);
--啟動自動追蹤觀察,並僅顯示所使用的資源數量
SQL> SET AUTOTRACE TRACEONLY STATISTICS;
SQL> SELECT * FROM t1 ORDER BY 1;
Statistics
----------------------------------------------------------
12 recursive calls
265 db block gets
1018 consistent gets
3080 physical reads
0 redo size
3880633 bytes sent via SQL*Net to client
50932 bytes received via SQL*Net from client
4594 SQL*Net roundtrips to/from client
0 sorts (memory)
1 sorts (disk) --當sort_area_size=64K時,需要進行磁碟排序
68888 rows processed
--將SORT_AREA_SIZE增加為10M
SQL> ALTER SESSION SET sort_area_size=10240000;
SQL> SELECT * FROM t1 ORDER BY 1;
Statistics
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
----------------------------------------------------------
10 recursive calls
9 db block gets
1018 consistent gets
1036 physical reads
0 redo size
3224976 bytes sent via SQL*Net to client
50932 bytes received via SQL*Net from client
4594 SQL*Net roundtrips to/from client
0 sorts (memory)
1 sorts (disk) --當sort_area_size=10M時,還是需要進行磁碟排序
68888 rows processed
--繼續增加SORT_AERA_SIZE的值到64M
SQL> ALTER SESSION SET sort_area_size=65536000;
SQL> SELECT * FROM t1 ORDER BY 1;
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
1018 consistent gets
0 physical reads
0 redo size
3226404 bytes sent via SQL*Net to client
50932 bytes received via SQL*Net from client
4594 SQL*Net roundtrips to/from client
1 sorts (memory) --只需進行記憶體排序即可
0 sorts (disk) --當sort_area_size=64M時,不需要進行磁碟排序
68888 rows processed
SQL> SET AUTOTRACE OFF --關閉自動追蹤
SQL> SELECT a.name,b.value
2> FROM v$statname a,v$sesstat b
3> WHERE a.statistic#=b.statistic#
4> AND (a.name LIKE 'session%ga memory%%' OR a.name LIKE '%direct temp%')
5> AND sid=(SELECT distinct sid FROM v$mystat);
NAME VALUE
------------------------------------------------------------------ ----------
session uga memory 170876
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
session uga memory max 9270372
session pga memory 473472
session pga memory max 9845120 --最大值
physical reads direct temporary tablespace 6373
physical writes direct temporary tablespace 6373
由上面的範例得知,當 SORT_AREA_SIZE 為 64K 或 10M 時,都必須進行磁碟排序(Disk
Sort:需要將被排序的資料,先儲存在暫時區段中,之後分批進行排序。)。如果將
SORT_AREA_SIZE 增為 64M 時,這時便可以在 PGA 中完成排序,即所謂的記憶體排序
(Memory Sort),記憶體排序的速度ㄧ定比磁碟排序的速度快。但也看到階段作業所使用的最
大 PGA 記憶體(SESSION PGA MEMORY MAX)的值由 539008 增加為 9845120,約為
9.4M。如果同時有 500 個階段作業進行同樣的 SQL 敘述句,那麼所有的 PGA 總和為
4.7G(9.4M*500),若加上 SGA 所使用的記憶體空間(假設為 2G),則此 Oracle 伺服器一共
消耗作業系統約 6.7G 的記憶體。如果這台伺服器的實體記憶體只有 4G,作業系統只好使用
虛擬記憶體(Virtual Memory)的機制來提供 Oracle 伺服器所需的記憶體。虛擬記憶體是使用
磁碟空間來模擬記憶體(UNIX 平台使用置換空間(Swap Space),Windows 平台使用分頁檔
(Pagefile)),這樣雖然可以提供更大的記憶體空間,但也會增加存取的時間,因為磁碟機的速
度遠慢於記憶體。所以這樣的 PGA 管理方式可能會造成記憶體不足的情況,進而導致 Oracle
伺服器的效能下滑。
但是這個問題不會馬上浮現,例如目前只有 100 個階段作業,即便每個階段作業需要 9.4M
的 PGA 空間,總共只需要 940M 的記憶體。加上 SGA(假設為 2G,此 Oracle 伺服器使用約
3G 的記憶體,不過因為作業系統有 4G 的實體記憶體,所以還不會出現使用虛擬記憶體的情
況。但隨著階段作業個數的增加,所有階段作業的 PGA 總和也逐漸地增加,一但 SGA 加
PGA 的總和大於實體記憶體後,作業系統便會開始使用虛擬記憶體。如此 Oracle 執行處理也
難免會使用到虛擬記憶體,進而造成 Oracle 伺服器的效能變差。為了避免使用虛擬記憶體所
帶來的效能問題,資料庫管理者可以犧牲個別的階段作業的排序效能,將*_AREA_SIZE 設定
值縮小,讓階段作業所能配置的 PGA 空間減少。這樣會造成階段作業進行排序時,因為使用
磁碟排序而造成排序時間增長。但也可以減少作業系統因實體記憶體不足而使用到虛擬記憶
體的可能性。
從 Oracle Database 9i 開始,管理者可以藉由將設定 PGA_AGGREGATE_TARGET(可以由
10M 到 4000G),啓用 PGA 自動管理。當啟用 PGA 自動管理後,每個階段作業可以使用的
最大 PGA 空間為 5%*PGA_AGGREGATE_TARGET。若為平行操作(Parallel Operation)最
大可達 30%*PGA_AGGREGATE_TARGET。不過 PGA 自動管理最重要的特點在於當每次
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
排序動作完成後,所配置的 PGA 空間將會回收,不再繼續保留給伺服器處理作業。而 Oracle
伺服器盡量將 PGA 總和維持在 PGA_AGGREGATE_TARGET 設定值之下,然而還是有些記
憶體是不可回收的(例如:每個階段作業的 PGA 空間至少需要 250K),PGA 自動管理所帶來
的好處是 Oracle 伺服器所使用的記憶體,可以控制在一定的範圍內。只要不超過實體記憶體,
便不會使用虛擬記憶體的問題。不過 PGA 自動管理所帶來的副作用,便是單一階段作業的排
序效能可能受到影響。
--啟用PGA自動管理,只要將pga_aggregate_target設定即可
SQL> ALTER SYSTEM SET pga_aggregate_target=100M;
SQL> SHOW PARAMETER pga_aggregate_target
NAME TYPE VALUE
------------------------------------------ ----------------------- ---------------------------
pga_aggregate_target big integer 100M
--當pga_aggregate_target大於0,則workarea_size_policy自動設為AUTO
SQL> SHOW PARAMETER workarea_size_policy
NAME TYPE VALUE
------------------------------------------ ---------------------- -----------------------------
workarea_size_policy string AUTO
啟用 PGA 自動管理後,資料庫管理者可以由 V$PGA_TARGET_ADVICE 得知,目前的
PGA_AGGREGATE_TARGET 是否足夠。
SQL> select pga_target_for_estimate pga_target,pga_target_factor size_factor,estd_time,
estd_pga_cache_hit_percentage hitratio from v$pga_target_advice;
PGA_TARGET SIZE_FACTOR ESTD_TIME HITRATIO
------------------- ---------------------- ----------------------- ----------
13107200 .125 5029 48
26214400 .25 5029 48
52428800 .5 5029 48
78643200 .75 5029 48
104857600 1 3002 80
125829120 1.2 3002 80
146800640 1.4 3002 80
167772160 1.6 3002 80
188743680 1.8 3002 80
209715200 2 3002 80
314572800 3 2390 100
419430400 4 2390 100
629145600 6 2390 100
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
838860800 8 2390 100
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
由上面的範例可以知道,目前的 PGA_AGGREGATE_TARGET 設為 100M,因為
PGA_TARGET_FACTOR 為 1。同時可以知道如果 PGA_AGGREGATE_TARGET 增為
300M,將減少排序時間達 20%,使用記憶體排序的比率也可達到 100%。若減少
PGA_AGGREGATE_TARGET 為 75M,將導致排序時間增加為 167%,而記憶體排序的比
率也將降為 48%。所以如果還有多餘的實體記憶體可供使用,管理者應該考慮增加
PGA_AGGREGATE_TARGET 的值。不然至少不能再減少 PGA_AGGREGATE_TARGET 的
值了。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3.2 緩衝區快取(Buffer Cache)
當伺服器作業處理(Server Process)執行執行計畫時,利用緩衝區快取(Buffer Cache)將由資
料檔讀入的資料區塊(data block)快取起來。當執行其他的 SQL 敘述句時,如果需要相同的
資料區塊,便可以直接由緩衝區快取讀到所需的資料區塊,這種讀取模式稱作邏輯讀取
(Logical Read)。主要是利用記憶體的存取速度遠快過於磁碟機的優勢,將實體讀取轉換成邏
輯讀取。因此即便是 I/O 的總數量不變,但是整體 I/O 的時間卻可以大幅下降,如此便可以
縮短 SQL 敘述句的反應時間。
3.2.1 管理緩衝區快取
緩衝區快取用來存放伺服器處理作業由資料檔所讀入的資料區塊,因此緩衝區快取邏輯上被
切割為許多個緩衝,每個緩衝的大小與資料區塊的大小一致。因此緩衝(Buffer)依其內容與資
料檔的資料區塊是否一致,而分為下列幾類狀態:
可用緩衝(Free Buffer)/未使用緩衝(Unused Buffer)
目前此緩衝並沒有任何資料。這種情況並不常見,通常是在執行處理剛啓動或緩衝區快取的
空間剛被增加,才會有可能看到。資料庫管理者也可以使用 ALTER SYSTEM FLUSH
BUFFER_CACHE 的指令,將緩衝區快取的緩衝內容都清空,因此所有的緩衝都變成此種型
態。所以這個指令不適合在正式環境使用,因為沒有任何效能上的好處,反而造成更多的實
體 I/O,增加資料庫的 I/O 負擔。這個指令主要用在測試環境,在每次測試前清除前次測試所
帶來的緩衝快取,確保每次測試的環境一致。
乾淨緩衝(Clean Buffer)
目前此緩衝的內容與資料檔的資料區塊一致。這種情況有可能是此緩衝的內容剛被伺服器處
理作業由資料檔中讀進,而且緩衝的內容還沒有被改變。也可能剛剛這個緩衝還是髒緩衝,
可是現在已經被 DBWR 將緩衝內容寫到資料檔的資料區塊,因此緩衝的狀態就變成乾淨。
阻止的緩衝(Pinned Buffer)
目前此緩衝的內容正在被某個伺服器處理作業(Server Process)改變,因此不能被其他的伺服
器處理作業讀取或異動。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
髒緩衝(Dirty Buffer)
目前此緩衝的內容與資料檔資料區塊的內容不一致,因為伺服器處理作業已經改變緩衝的內
容。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
緩衝區快取是由下列的多個子緩衝快取空間所組成的:
1.Default Buffer Cache:DB_CACHE_SIZE
2.Keep Buffer Cache:DB_KEEP_CACHE_SIZE
3.Recycle Buffer Cache:DB_RECYCLE_CACHE_SIZE
4.Non-Standard Block Buffer Cache:DB_nK_CACHE_SIZE(n=2/4/8/16/32)
3.2.2 Least Recently Use 演算法
緩衝區快取通常已經是整個 SGA 佔最大比例的一塊空間,不過再怎麼大的緩衝區快取,與資
料庫相較下還是不夠大。同時伺服器處理作業(Server Process)在進行任何的資料操作(查詢
或異動)前,該操作所需的資料必須先被讀到緩衝區快取,才能進行資料操作。因此緩衝的內
容勢必將有置換的情況發生,因為緩衝的數量遠小於資料區塊的數量。那麼 Oracle 伺服器如
何決定哪些緩衝的內容將被取代,而哪些緩衝的內容不需要被取代?
Oracle 伺服器採用的是 LRU(Least Recent Used)機制,依每個緩衝的內容最近被存取的時
間及被存取的次數(Touch Count),排成一個串列(List),稱為 LRU 串列。這個串列有兩個端
點,一個端點稱為 MRU 端(Most Recently Uesd),越靠近 MRU 端的緩衝,表示其內容最近
才被存取且存取次數相對較多。另一個頭端為 LRU 端(Least Recently Used),越靠近 LRU
端的緩衝,表示其內容越久未被存取且存取次數相對較少。然而 LRU 串列的演算法經過長久
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
的演進,發展出下列幾種:Standard LRU 演算法、Modified LRU 演算法與 Touch Count
LRU 演算法。
標準的 LRU 演算法(Standard LRU Algorithm)
當伺服器處理作業發現它所需要的資料區塊,目前不存在於緩衝區塊快取,因此需要將那些
資料區塊由資料檔讀到緩衝區快取時,便開始由 LRU 串列的 LRU 端,開始尋找狀態為可用
或乾淨的緩衝。找到足夠的可用或乾淨的緩衝後,伺服器處理作業將資料區塊的內容讀到那
些緩衝之中,然後才進行後續的資料操作。而這些緩衝因為是最近被存取的緩衝,因此緩衝
在 LRU 串列的位置也被移到 MRU 端。因此 LRU 串列的其他緩衝就向 LRU 端遞移。
這種資料讀取的方式稱為實體讀取(Physical Read),需要消耗 I/O 頻寬與較長的讀取時間。
如果伺服器處理作業發現所需要的資料區塊已經存在於緩衝區快取的某些緩衝中,便直接使
用這些緩衝的內容進行資料操作。這種資料讀取的方式稱為邏輯讀取(Logical Read),不須消
耗 I/O 頻寬且讀取時間較短。當然這些緩衝的位置也被移到 LRU 串列的 MRU 端。
缺點:當對大型的表格(Table)進行全表格掃描(Full Table Scan)存取時,整個表格的資料區
塊需要讀到緩衝區快取。因為需要大量的緩衝,所以導致可用或乾淨緩衝的內容被置換。若
未使用或乾淨緩衝的個數不足時,將造成許多髒緩衝被寫回資料檔,將緩衝狀態變成乾淨後,
才能提供足夠的緩衝數量。然而通常使用全表格掃描所存取的資料區塊,被重複使用的機率
相當小。而之前被置換的資料區塊內容,反而更有可能被反覆使用。因此標準的 LRU 演算法
在遇到全表格掃描時,反而會造成更多的實體讀取,造成資料庫的效能因過多的實體 I/O 而
下降。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
修改過的 LRU 演算法(Modified LRU Algorithm)
為解決標準的 LRU 演算法在處理全表格掃描所發生的問題,Oracle 公司對標準的 LRU 演算
法進行修改。Oracle Database 7 開始使用這種修改過的 LRU 演算法,當伺服器處理作業對
某個表格進行全表格掃描存取時,會根據表格的資料區塊數量與參數檔的
cache_table_threshold 參數值進行比較,如果表格的資料區塊數量小於
cache_table_threshold 參數值,則這些資料區塊讀到緩衝區快取後,它們將被放置在 LRU
串列的 MRU 端。因為對小型表格進行全表格掃描存取是比較有效率且常見的方式,所以藉由
設定 cache_table_threshold 參數來界定何者危大型表格。若為小型表格則如同標準的 LRU
演算法一樣,將區塊位置放在 MRU 端。但若表格的資料區塊數量大於
cache_table_threshold 參數值,讀入的區塊則放在 LRU 端。
此外還有一個隱藏參數_small_table_threshold 也會影響全表格掃描存取時,表格的資料區塊
是否會放在 LRU 串列的 MRU 端。當表格的資料區塊數量小於_small_table_threshold 時,
這些經由全表格掃描讀入的表格區塊將放在 LRU 串列的 MRU 端。所以修改過的 LRU 演算法
便可以解決標準的 LRU 演算法在遇到全表格掃描存取所發生的問題。
缺點:如果使用索引範圍掃描存取表格,而需要讀取的索引樹葉區塊數量相當多。因為所讀
取的區塊為索引的樹葉區塊,同時並不是全表格掃描存取,這時將出現類似標準的 LRU 演算
法遇到全表格掃描時的問題。只是對象換成大量的索引樹葉區塊。
多個緩衝池機制(Multiple Buffer Pool)
為解決讀取大量索引樹葉區塊所發生的問題,Oracle 公司在 Oracle Database 8 時提出多個
緩衝池的架構。讓資料庫管理者最多可以將緩衝區快取分割為三部份:保存池(Keep Pool 使
用 DB_KEEP_POOL_SIZE 參數設定其大小)、回收池(Recycle Pool 使用
DB_RECYCLE_POOL_SIZE 參數設定其大小)及預設池(Default Pool 使用
DB_CACHE_SIZE 參數設定其大小)。每個緩衝池至少由一個工作集管理(Working set),每
個工作集由一個 LRU 串列與檢查點串列(Checkpoint Queue List)組成。所以如果其中一個
緩衝池發生緩衝內容置換的情況,其他的緩衝池並不會受到影響。
因此資料庫管理者可以將常用的資料區塊放在保存池,但要注意不要將太多的資料區塊放在
保存池中,因為需要放入保存池的資料區塊數量大於保存池的緩衝數量時,還是會使用 LRU
演算法進行緩衝內容的置換。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
可以將那些 SQL 敘述句執行完畢後,便不會再用到的資料區塊,放在回收池中。但不要讓回
收池太小,而造成 SQL 敘述句還未執行完畢,所需的資料區塊又因為回收池太小而需要再次
由資料檔讀到回收池中。
至於預設池是用來放置那些未明確指定使用保存池或回收池的資料區塊。
當資料區塊被讀取時,將依照資料區塊所屬的區段(Segment)的 storage 參數所指定的緩衝池,
決定將資料區塊讀到哪個緩衝池。以下是相關的指令範例:
--使用BUFFER_POOL參數設定區段的資料區塊所屬的緩衝池,
--若沒有明確指定,則預設使用預設池(default)
--CREATE TABLE abc (a NUMBER) STORAGE (BUFFER_POOL {default|keep|recycle})
--CREATE INDEX abc_idx ON abc(a) STORAGE (BUFFER_POOL {default|keep|recycle})
--也可以在建立區段後,更改資料區塊所使用的緩衝池
--ALTER TABLE abc STORAGE (BUFFER_POOL keep)
--ALTER INDEX abc_idx STORAGE(BUFFER_POOL recycle)
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
所以資料庫管理者可以將索引的資料區設定存放在回收池中,因此當對一個大的索引進行範
圍掃描時,被讀取的索引樹葉區塊將被放到回收池中。即便造成回收池中的緩衝發生內容置
換的情況,也不會影響到保存池或預設池的資料區塊,這樣便可以解決修改過的 LRU 演算法
在讀取大量索引樹葉區塊所遇到的問題。
使用計數 LRU 演算法(Touch-Count LRU Algorithm)
從 Oracle Database 8i 開始,Oracle 資料庫使用 Touch-Count LRU 演算法取代之前使用的
修改的 LRU 演算法。新演算法的基本精神是每個資料區塊是否能被保留在緩衝區快取中,必
須依其被存取的次數與被存取的時間為依據,而不再只使用依存取時間為基準。因此現在的
LRU 串列被分成兩部份:一部份稱做熱區(Hot region),在熱區的資料區塊,稱做熱區塊。另
一部份則稱做冷區(Cold region),在冷區的資料區塊,稱做冷區塊。基本上熱區與冷區的大
小相當。不過兩者的比率可以透過隱藏參數_db_percent_hot_default 來調整。
當資料區塊被讀到緩衝區快取時,它將被放在熱區與冷區的中間,稱做中間點插入(Midpoint
Insertion),實際上所插入的位置屬於熱區的一部份。此後資料區塊將依其被存取的次數,來
決定未來資料區塊的位置,是放在 LRU 串列的 MRU 端(持續在熱區)或逐漸向 LRU 端移動(進
入冷區)。
理論上當資料區塊每被存取一次,其使用計數(touch count)就會加一。然而使用計數 LRU 演
算法並不是如此,因為有時資料區塊會在短時間內被多次存取,但過了這段時間後,卻不再
使用該資料區塊。因此如果每存取一次就增加一次使用計數,可能導致誤判。Oracle 資料庫
採取在一段時間區間,不管資料區塊被存取幾次,其使用計數僅增加一的方式來因應這種可
能的問題。這個時間區間預設為 3 秒鐘,資料庫管理者可以用_db_aging_touch_time 來調整
區間長度。除外資料區塊的使用計數增加與資料區塊在 LRU 串列的位置是無關的,使用計數
表示資料的熱門程度,在 LRU 串列的位置決定被置換內容的優先順序。
F
12
D
0
F
0
D
2
F
2
P
0
F
1
P
10
F
1
F
15
D
8
D
10
LRU ListMRU End LRU End
Hot Region Cold Region
Midpoint
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
資料區塊位置的移動
當伺服器處理作業在 LRU 串列中尋找可用或乾淨的緩衝時,或 DBWR 在 LRU 串列中尋找髒
緩衝時。如果發現到某個資料區塊的使用計數大於 2 的時候,則將該區塊的位置移動到 LRU
串列的 MRU 端,並將其使用計數設為 0。若發現乾淨緩衝的資料區塊的使用計數小於 2,伺
服器處理作業便選擇該緩衝當做未來讀入資料區塊的緩衝。可以藉由設定
_db_aging_hot_criteria 參數調整此使用計數大小。
當某個資料區塊被移到 LRU 串列的 MRU 端或一個新的資料區塊被新增到中間點時,至少都
會造成一個資料區塊由熱區被擠到冷區。若資料區塊由熱區移到冷區時,其使用計數將被設
定為 1,不論原來的使用計數為何。資料庫管理者可以藉由_db_aging_cool_count 調整當資
料區塊由熱區移到冷區時,使用計數的設定值。
因此可以得知使用計數 LRU 演算法,除考慮資料區塊的存取時間順序外,還考慮資料區塊的
存取次數,來決定資料區塊是否可以繼續留在緩衝區快取。讓目前保留在緩衝區快取的資料
區塊,一定是最近而且最常使用的(recently,frequent used)資料區塊。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
3.3 共用集區(Shared pool)
當一個 SQL 敘述句由使用者處理作業(User Process)傳遞到伺服器作業處理(Server Process)
時,伺服器作業處理必須先將該 SQL 敘述句解析為執行計畫,並將執行計畫儲存到共用集區
的程式庫快取(Library Cache)後,接著才能使用該執行計畫進行後續的操作。為何要先將執
行計畫先存放在共用集區後,才能繼續執行?因為當下次使用者執行相同的 SQL 敘述句時,
便可以直接由程式庫快取取得之前產生的執行計畫,就不需要再次硬解析(Hard Parse),而只
需要進行軟解析(Soft Parse)即可。這樣的機制可以大幅地減少硬解析的次數,對提昇 Oracle
伺服器的效能有相當大的幫助。
3.3.1 結果集快取(Result Cache)
從 Oracle Database 11g 開始,Oracle 伺服器更進一步將 SQL 敘述句的結果,直接快取存
放在 Result Cache。因此當下次執行相同的 SQL 敘述句時,就不需要再次執行,直接將存
放在 Result Cache 的結果,直接回傳給使用者即可,如此可以得到更短的反應時間。同時
Oracle Database 11g 會自動偵測結果集的正確性,如果相關資料表的內容有變動,將會將
該結果集設定為失效,下次執行相同的 SQL 敘述句時,會重新執行該敘述句產生最新的結果
集並再次快取到 Result Cache 中。
結果集快取參數
RESULT_CACHE_MODE
RESULT_CACHE_MODE 決定 SQL 敘述句的結果是否要被快取到 Result Cache 中,如果
設定為 MANUAL,查詢指令必須加上 RESULT_CACHE 的 HINT,其執行結果才能被快取。
反之為設定為 FORCE,則執行結果會自動被快取,除非加上 NO_RESULT_CACHE 才會不
使用被快取。而 RESULT_CACHE_MODE 設定為 AUTO 時,則讓 Oracle 伺服器自動判斷是
否要將其執行結果快取。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
RESULT_CACHE_MAX_SIZE
RESULT_CACHE_MAX_SIZE 設定結果集快取最大可以使用的大小,如果將其設為 0 則為
關閉結果集快取的功能。若明確設定此參數值時,請注意此參數不能大於共用集區大小的
75%。
若沒有明確設定此值則依下列機制設定︰
• 如果有設定 MEMORY_TARGET 參數值,則 RESULT_CACHE_MAX_SIZE 為
0.25%*MEMORY_TARGET。
• 如果沒有設定 MEMORY_TARGET 參數值,但有設定 SGA_TARGET,則
RESULT_CACHE_MAX_SIZE 為 0.5%*SGA_TARGET。
• 如果 MEMORY_TARGET 與 SGA_TARGET 都沒有設定,則
RESULT_CACHE_MAX_SIZE 為 1.0%*SHARED_POOL_SIZE。
建立相關測試環境
SQL> CONNECT / AS sysdba --以sys身份登入資料庫
--建立角色plustrace,將plustrace角色授權給新建的使用者,讓他可以使用autotrace的功能
--用來觀察結果集快取操作狀況
SQL> @$ORACLE_HOME/sqlplus/admin/plustrce.sql
--建立一個測試的資料庫使用者,因為在11.1.0.7時,結果集快取機制不能使用在sys的階段作業
--在11.1.0.8以後,結果集快取的功能也可以用在sys所建立的階段作業上
SQL> CREATE USER frank IDENTIFIED BY oracle
2 DEFAULT TBALESPACE users
3 QUOTA UNLIMITED ON users;
SQL> GRANT CONNECT,RESOURCE,PLUSTRACE TO frank;
SQL> CREATE TABLE frank.big1 AS SELECT * FROM dba_objects; --建立測試表格
SQL> execute dbms_stats.gather_table_stats('FRANK','BIG1'); --收集表格的統計資料
SQL> show parameter result_cache_mode
NAME TYPE VALUE
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
------------------------------- ----------- ------------------------------
result_cache_mode string MANUAL --查詢敘述句不會自動產生與使用結果集快取
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
可以使用 V$RESULT_CACHE_DEPENDENCY 的內容,查知與哪些表格有被快取。
如果需要察看目前的 Result Cache 的狀態,可以透過 V$RESULT_CACHE_STATISTICS
或 DBMS_RESULT_CACHE.MEMORY_REPORT 得知。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
結果集快取的有效性由 Oracle 伺服器自動維護,例如當結果集快取的相關表格內容被異動後,
已快取的結果集狀態將被設定為失效(Invalid),同時與結果集相關的相依關係也將被移除。而
且最佳化處理程式並不會使用一個失效的結果集快取,所以不用擔心資料的正確性。
Chapter 3 – Oracle Instance
Oracle Database Management Best Practice
結果集快取可以大幅降低 SQL 查詢敘述句所需要的反應時間,尤其當記憶體成本越來越低的
現在,相信未來將會有更多的功能,會使用類似的技巧,來減少 SQL 敘述句的反應時間。
不過結果集快取並不適合用在線上交易處理(OLTP)型態的資料庫,因為執行結果快取後,如
果相關的表格內容被異動,結果集的狀態將自動變成失效,而最佳化處理程式無法使用失效
的結果集。而資料倉儲型態的資料庫不常變動資料內容,所以結果集的有效期間可以維持的
較久,因此結果集快取比較適合用在資料倉儲型態的資料庫。
結論
系統整體區域(System Global Area)是執行處理中最重要的元件,Oracle 伺服器的效能與系
統整體區域的管理息息相關。緩衝區快取與共用集區則是 SGA 最重要的兩個元件,經過第二
章與本章的說明後,資料庫管理者應該能夠了解緩衝區快取與共用集區的用途與基本管理,
也能夠分辨自動記憶體管理與自動共用記憶體管理。

More Related Content

What's hot

Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Aaron Shilo
 
UKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction LocksUKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction Locks
Kyle Hailey
 
Oracle db performance tuning
Oracle db performance tuningOracle db performance tuning
Oracle db performance tuning
Simon Huang
 

What's hot (20)

Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11gOracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
Oracle管理藝術第1章 在Linux作業體統安裝Oracle 11g
 
Oracle SQL 1 Day Tutorial
Oracle SQL 1 Day TutorialOracle SQL 1 Day Tutorial
Oracle SQL 1 Day Tutorial
 
Oracle Database SQL Tuning Concept
Oracle Database SQL Tuning ConceptOracle Database SQL Tuning Concept
Oracle Database SQL Tuning Concept
 
Oracle Database Management Basic 1
Oracle Database Management Basic 1Oracle Database Management Basic 1
Oracle Database Management Basic 1
 
Oracle Database Performance Tuning Concept
Oracle Database Performance Tuning ConceptOracle Database Performance Tuning Concept
Oracle Database Performance Tuning Concept
 
Understanding index
Understanding indexUnderstanding index
Understanding index
 
Databases on AWS
Databases on AWSDatabases on AWS
Databases on AWS
 
Oracle sql high performance tuning
Oracle sql high performance tuningOracle sql high performance tuning
Oracle sql high performance tuning
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
 
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAsOracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
 
Advanced PLSQL Optimizing for Better Performance
Advanced PLSQL Optimizing for Better PerformanceAdvanced PLSQL Optimizing for Better Performance
Advanced PLSQL Optimizing for Better Performance
 
Exadata master series_asm_2020
Exadata master series_asm_2020Exadata master series_asm_2020
Exadata master series_asm_2020
 
Oracle Database Performance Tuning Basics
Oracle Database Performance Tuning BasicsOracle Database Performance Tuning Basics
Oracle Database Performance Tuning Basics
 
UKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction LocksUKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction Locks
 
Oracle db performance tuning
Oracle db performance tuningOracle db performance tuning
Oracle db performance tuning
 
Oracle RAC 19c: Best Practices and Secret Internals
Oracle RAC 19c: Best Practices and Secret InternalsOracle RAC 19c: Best Practices and Secret Internals
Oracle RAC 19c: Best Practices and Secret Internals
 
Smart monitoring how does oracle rac manage resource, state ukoug19
Smart monitoring how does oracle rac manage resource, state ukoug19Smart monitoring how does oracle rac manage resource, state ukoug19
Smart monitoring how does oracle rac manage resource, state ukoug19
 
Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2
Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2
Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2
 
監査ログをもっと身近に!〜統合監査のすすめ〜
監査ログをもっと身近に!〜統合監査のすすめ〜監査ログをもっと身近に!〜統合監査のすすめ〜
監査ログをもっと身近に!〜統合監査のすすめ〜
 
Oracle RAC 12c Practical Performance Management and Tuning OOW13 [CON8825]
Oracle RAC 12c Practical Performance Management and Tuning OOW13 [CON8825]Oracle RAC 12c Practical Performance Management and Tuning OOW13 [CON8825]
Oracle RAC 12c Practical Performance Management and Tuning OOW13 [CON8825]
 

Similar to Oracle SGA 介紹

深入了解Oracle自动内存管理asmm
深入了解Oracle自动内存管理asmm深入了解Oracle自动内存管理asmm
深入了解Oracle自动内存管理asmm
maclean liu
 
A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题
WASecurity
 
【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410
【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410
【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410
maclean liu
 
Mysql性能分析之临时表(共享)
Mysql性能分析之临时表(共享)Mysql性能分析之临时表(共享)
Mysql性能分析之临时表(共享)
beiyu95
 
11g新特性streams同步捕获
11g新特性streams同步捕获11g新特性streams同步捕获
11g新特性streams同步捕获
maclean liu
 
Mysql handlersocket
Mysql handlersocketMysql handlersocket
Mysql handlersocket
pwesh
 
【Ask maclean技术分享】oracle dba技能列表 z
【Ask maclean技术分享】oracle dba技能列表 z【Ask maclean技术分享】oracle dba技能列表 z
【Ask maclean技术分享】oracle dba技能列表 z
maclean liu
 
Itpub电子杂志(第五期)
Itpub电子杂志(第五期)Itpub电子杂志(第五期)
Itpub电子杂志(第五期)
yiditushe
 

Similar to Oracle SGA 介紹 (20)

深入了解Oracle自动内存管理asmm
深入了解Oracle自动内存管理asmm深入了解Oracle自动内存管理asmm
深入了解Oracle自动内存管理asmm
 
12, OCP - performance tuning
12, OCP - performance tuning12, OCP - performance tuning
12, OCP - performance tuning
 
A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题A.oracle 查询结果的缓存问题
A.oracle 查询结果的缓存问题
 
【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410
【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410
【Maclean liu技术分享】开oracle调优鹰眼,深入理解awr性能报告 第二讲 正式版 20130410
 
7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery
 
1, OCP - architecture intro
1, OCP - architecture intro1, OCP - architecture intro
1, OCP - architecture intro
 
Mybatis学习培训
Mybatis学习培训Mybatis学习培训
Mybatis学习培训
 
11, OCP - awr & alert system
11, OCP - awr & alert system11, OCP - awr & alert system
11, OCP - awr & alert system
 
Mysql性能分析之临时表(共享)
Mysql性能分析之临时表(共享)Mysql性能分析之临时表(共享)
Mysql性能分析之临时表(共享)
 
11g新特性streams同步捕获
11g新特性streams同步捕获11g新特性streams同步捕获
11g新特性streams同步捕获
 
【Ask maclean技术分享oracle数据库优化】awr鹰眼系列awr报告全面指标分析
【Ask maclean技术分享oracle数据库优化】awr鹰眼系列awr报告全面指标分析【Ask maclean技术分享oracle数据库优化】awr鹰眼系列awr报告全面指标分析
【Ask maclean技术分享oracle数据库优化】awr鹰眼系列awr报告全面指标分析
 
5, OCP - oracle storage
5, OCP - oracle storage5, OCP - oracle storage
5, OCP - oracle storage
 
Mysql handlersocket
Mysql handlersocketMysql handlersocket
Mysql handlersocket
 
3, OCP - instance management
3, OCP - instance management3, OCP - instance management
3, OCP - instance management
 
Installation and configuration 11g r2 asm using job role separation(grid & or...
Installation and configuration 11g r2 asm using job role separation(grid & or...Installation and configuration 11g r2 asm using job role separation(grid & or...
Installation and configuration 11g r2 asm using job role separation(grid & or...
 
H wand os
H wand osH wand os
H wand os
 
H wand os
H wand osH wand os
H wand os
 
【Ask maclean技术分享】oracle dba技能列表 z
【Ask maclean技术分享】oracle dba技能列表 z【Ask maclean技术分享】oracle dba技能列表 z
【Ask maclean技术分享】oracle dba技能列表 z
 
Nginx共享内存
Nginx共享内存Nginx共享内存
Nginx共享内存
 
Itpub电子杂志(第五期)
Itpub电子杂志(第五期)Itpub电子杂志(第五期)
Itpub电子杂志(第五期)
 

More from Chien Chung Shen (6)

Awsomeday ntc
Awsomeday ntcAwsomeday ntc
Awsomeday ntc
 
MySQL SQL Tutorial
MySQL SQL TutorialMySQL SQL Tutorial
MySQL SQL Tutorial
 
Oracle 12cR1 In-Memory Column Store
Oracle 12cR1 In-Memory Column StoreOracle 12cR1 In-Memory Column Store
Oracle 12cR1 In-Memory Column Store
 
Mssql to oracle
Mssql to oracleMssql to oracle
Mssql to oracle
 
Oracle Database Undo Segment Operation Concept
Oracle Database Undo Segment Operation ConceptOracle Database Undo Segment Operation Concept
Oracle Database Undo Segment Operation Concept
 
Hadoop Essential for Oracle Professionals
Hadoop Essential for Oracle ProfessionalsHadoop Essential for Oracle Professionals
Hadoop Essential for Oracle Professionals
 

Oracle SGA 介紹

  • 1. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 第三章 執行處理的記憶體管理 前言 Oracle 執行處理(Instance)雖說由系統整體區域(SGA)與背景處理作業(Background Process) 組成,但是主要影響效能的關鍵,多為系統整體區域的共用記憶體管理不當所造成。而系統 整體區域中最重要的共用記憶體元件為緩衝區快取(Buffer Cache)與共用集區(Shared Pool)。 因此本章特別更進一步說明系統整體區域的記憶體管理,以及緩衝區快取與共用集區的內容, 希望可以讓資料庫管理者真正了解系統整體區域的內涵。 3.1 記憶體管理 Oracle 伺服器所使用到的記憶體可分為兩種:系統整體區域(System Global Area-縮寫為 SGA)、程式整體區域(Program Global Area-縮寫為 PGA)。每個 Oracle 執行處理只有一個 SGA,放在 SGA 的資料可被所有的背景處理作業與伺服器處理作業(Server Process)所存取。 但是每個背景處理作業或伺服器處理作業各自有一個私有的記憶空間,稱作 PGA,放在 PGA 的資料只有背景處理作業或伺服器處理作業自己才能存取。
  • 2. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 在整個執行處理的管理工作中,以 SGA 的設定與管理最為複雜。因為 SGA 是由許多共用記 憶體元件組成,常見的有共用集區-Shared Pool、緩衝區快取-Buffer Cache、重做日誌緩衝 區-Redo Log Buffer、大型集區-Large Pool、Java 集區-Java Pool、串流集區-Streams Pool 等。然而不同型態的 SQL 敘述句使用到的共用記憶體元件也有所不同,因此共用記憶 體元件需要隨時著資料庫的不同狀況而調整,才能得到最佳的系統效能。也因為如此資料庫 管理者得時時盯著資料庫,適時地調整共用記憶體元件的大小,才能讓 Oracle 伺服器的效能 達到最佳。但這樣的監控方式對資料庫管理者來說,無疑是相當大的負擔。雖然從 Oracle Database 9i 開始,資料庫管理者可以在不關閉執行處理的狀態下,動態地調整某些共用記憶 體元件的大小,可是共用記憶體元件的大小還是需要人為調整。 不過 Oracle Database 10g 開始,資料庫管理者可以藉由自動共用記憶體管理(Automatic Shared Memory Management-縮寫為 ASMM),讓執行處理自動依據 Oracle 伺服器狀況, 將共用記憶體分配給目前最需要的元件。這個功能一方面可以減輕資料庫管理者的負擔,另 一方面也可以減少 ORA-4031 記憶體不足的錯誤發生。
  • 3. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3.1.1 自動記憶體管理(Automatic Memory Management) Oracle Database 11g 的自動記憶體管理(Automatic Memory Management-縮寫為 AMM)讓 資料庫管理者只需指定整個 Oracle 伺服器所能使用的最大記憶體空間,不需個別設定 SGA 或 PGA 的大小,之後 Oracle 執行處理自動依 Oracle 伺服器狀態調整 SGA 與 PGA 的大小, 以及 SGA 的其他共用記憶體元件的大小(緩衝區快取、共用集區、大型集區、Java 集區、 Streams 集區)。 當執行處理剛啓動時,SGA 佔記憶體目標的 60%,而 PGA 佔 40%,之後隨著 Oracle 伺服 器狀態,由背景處理作業 Memory Management(MMAN)動態地調整兩者的比率以達到 Oracle 伺服器的最佳效能。資料庫管理者如果想要啓用(Enable)自動記憶體管理機制,可以 藉由設定 MEMORY_MAX_TARGET 與 MEMORY_TARGET 這兩個參數來啟動。需要注意的 事為 MEMORY_TARGET 必須小於 MEMORY_MAX_TARGET。 啟動自動記憶體管理 1.取得 SYSDBA 的權限。 在 SQL*PLUS 環境下執行”SHOW USER”指令,出現的使用者若為 SYS 即表示此階段作 業已經取得 SYSDBA 權限。因為從 Oracle Database 9i 開始,使用者 SYS 只能使用 SYSDBA 或 SYSOPER 身分登入。 [ora11g@elinux5 ~]$ export $ORACLE_SID=ora11g /*設定執行處理的名字*/ [ora11g@elinux5 ~]$ sqlplus / AS SYSDBA /*以OS驗證,取得SYSDBA權限*/ SQL> SHOW USER USER is “SYS” 2.是否啓用自動記憶體管理。執行”SHOW PARAMETER target”來查看,若 MEMORY_TARGET 值為 0,表示尚未啓動自動記憶體管理。若 MEMORY_TARGET 值大於 0,則表示已經使用自動記憶體管理。 SQL> SHOW PARAMETER target NAME TYPE VALUE ------------------------------------------ ---------------- ------------------------------ memory_max_target big integer 0 --記憶體最大目標 memory_target big integer 0 --記憶體目標 pga_aggregate_target big integer 100M --PGA聚總目標
  • 4. Chapter 3 – Oracle Instance Oracle Database Management Best Practice sga_target big integer 304M --SGA目標 3.計算所需要的記憶體總大小。將 SGA 目標(SGA_TARGET)與 PGA 聚總目標 (PGA_AGGREGATE_TARGET)相加即可,不過因為 PGA 聚總目標是軟限制(soft limit),實 際使用的 PGA 總空間可能超過 PGA 聚總目標。所以要找出目前 Oracle 伺服器曾經使用到的 PGA 最大值,與 PGA 聚總目標比較,取兩者之中較大的值為代表。之後將所得的 PGA 使用 值與 SGA 目標相加,這樣所得到的結果才能符合目前 Oracle 伺服器的需求。 SQL> SELECT value FROM v$pgastat 2> WHERE name='maximum PGA allocated'; --曾經使用過的最大PGA值 VALUE ---------------- 244552704 依照範例來看,目前 Oracle 伺服器中 PGA 空間最大曾經用到 233M,較 PGA 聚總目標 (100M)來得大。所以記憶體目標(MEMORY_TARGET)應該設為 537M(233M+304M)。 4.設定 MEMORY_TARGET 與 MEMORY_MAX_TARGET。MEMORY_MAX_TARGET 是用 來設定 Oracle Servery 最大可使用多少的記憶體,MEMORY_MAX_TARGET≧ MEMORY_TARGET。通常管理者只需要設定 MEMORY_TARGET 即可,因為 MEMORY_MAX_TARGET 的值預設與 MEMORY_TARGET 一樣。若設定 MEMORY_MAX_TARGET 而且大於 MEMORY_TARGET,則主要是用在尋找最適當的 MEMORY_TARGET 時,可以讓 MEMORY_TARGET 及時增加空間,而不需要重新啓動 Oracle Instance。 SQL> ALTER SYSTEM SET memory_target=537M SCOPE=SPFILE; /*不能直接修改memory_target的原因,是memory_target必須小於或等於memory_max_targe t,而現在memory_max_target為0,且memory_max_target不能動態改變。*/ SQL> ALTER SYSTEM SET sga_target=0; SQL> ALTER SYSTEM SET pga_aggregate_target=0; --重新啟動執行處理,讓memory_target設定生效 SQL> SHUTDOWN IMMEDIATE SQL> STARTUP SQL> SHOW PARAMETER target NAME TYPE VALUE ------------------------------------------ ----------------------- ---------- memory_max_target big integer 544M
  • 5. Chapter 3 – Oracle Instance Oracle Database Management Best Practice memory_target big integer 544M pga_aggregate_target big integer 0 sga_target big integer 0 /*出現的不是537M,而是544M.因為MEMORY_TARGET要為Granule的整數倍,目前的Granule s ize為4M.*/ 但是目前 MEMORY_TARGET 設定為 544M 到底夠不夠用?管理者可已由 V$ MEMORY_TARGET_ADVICE 得知,若加大 MEMORY_TARGET 的值是否有好處?反之若 減少 MEMORY_TARGET 的值是否影響整體的效能? SQL> SELECT memory_size,memory_size_factor size_factor, 2> estd_db_time db_time,estd_db_time_factor db_time_factor 3> FROM v$memory_target_advice; MEMORY_SIZE SIZE_FACTOR DB_TIME DB_TIME_FACTOR ---------------------- ----------------------- -------------------- -------------------------- 544 1 443 1 272 .5 444 1 408 .75 444 1 680 1.25 444 1 816 1.5 443 .9983 952 1.75 443 .9983 1088 2 443 .9983 --將記憶體目標設定為272M SQL> ALTER SYSTEM SET memory_target=272M;
  • 6. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 由上面的範例可以看到目前的 MEMORY_TARGET 為 544M,因為 MEMORY_SIZE_FACTOR 為 1。同時可以得知,即使將 MEMORY_TARGET 增加為 816M, 可以減少一些 DB_TIME,但是差距實在太小,以比率而言也只有 0.0017。這時資料庫管理 者便不應該將 SGA_TARGET 設為 816M,因為只有浪費記憶體而已。如果資料庫管理者這 時將 MEMORY_TARGET 設為 272M,DB_TIME 沒有明顯的增加,而 Oracle 伺服器所佔用 的記憶體卻可以大幅下降,而節省下來的記憶體空間可以給作業系統的其他服務使用,這些 其他服務當然也包含其他的 Oracle 伺服器。那麼資料庫管理者何樂不為呢?那為何不選擇 408M 呢?因為 MEMORY_TARGET 設為 408M,得到]DB_TIME 卻與設為 272M 相同,這 樣只有浪費不必要的記憶體,並沒有其他的好處。所以依範例的結果來看, MEMORY_TARGET 降為 272M 是最好的選擇。
  • 7. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 資料庫管理者也可以透過資料庫控制(Database Control)或網格控制(Grid Control)的管理界 面,使用記憶體建議(Memory Advisor)程式得到相關的訊息。 當啟用自動記憶體管理後,資料庫管理者可由 V$MEMORY_DYNAMIC_COMPONENTS,得 到目前共用記憶體元件的大小以及可以那些共用記憶體元件可以動態地變更大小。
  • 8. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 雖然使用自動記憶體管理時,Oracle 伺服器可以自動管理一些共用記憶體元件的大小,但不 是每個共用記憶體元件的大小都可以被自動管理。資料庫管理者可以由 V$SGA_INFO 得知目 前共用記憶體元件的大小及哪些共用記憶體元件的大小可以自動管理。如果 RESIZEABLE 為 YES,表示這個共用記憶體元件的大小可以被 Oracle 執行處理自動管理。 ◎Oracle11g:SHARED POOL、LARGE POOL、JAVA POOL、STREAMS POOL、 DEFAULT BUFFER CACHE、SHARED IO POOL。注意:雖然 PGA 的空間也可以被自動 管理,但不會出現在下面的範例中,因為 PGA 不是共享記憶體的一部份。 SGA 是由多個不同用途的共用記憶體元件所組成,但不是每個共用記憶體元件都可以被自動 管理。有些共用記憶體元件從執行處理啓動後,便不能變更其大小。例如:固定 SGA(Fixed SGA)、日誌緩衝(Log Buffer)、結果集快取(Result Cache)。而有些元件的大小雖然可以動 態改變,但必須由資料庫管理者自行變更,而不能由 Oracle 執行處理自動管理。例如:保存 緩衝快取(KEEP BUFFER CACHE)、回收緩衝快取(RECYCLE BUFFER CACHE)、預設
  • 9. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 2K 緩衝快取(DEFAULT 2K BUFFER CACHE)、預設 4K 緩衝快取(DEFAULT 4K BUFFER CACHE)、預設 8K 緩衝快取(DEFAULT 8K BUFFER CACHE)、預設 16K 緩衝快取 (DEFAULT 16K BUFFER CACHE)、預設 32K 緩衝快取(DEFAULT 32K BUFFER CACHE)、自動儲存管理緩衝快取(ASM BUFFER CACHE)。 因此使用自動記憶體管理時,MMAN 會先扣除不能被自動管理的記憶體空間後,然後才將剩 餘的共用記憶體空間依照 Oracle 伺服器的狀況,將共用記憶體分配給共用集區(SHARED POOL)、大型集區(LARGE POOL)、JAVA 集區(JAVA POOL)、STREAMS 集區 (STREAMS POOL)、預設緩衝快取(DEFAULT BUFFER CACHE)、共用 IO 集區(SHARED IO POOL)及 PGA 目標(PGA TARGET)。
  • 10. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3.1.2 自動共用記憶體管理(Automatic Shared Memory Management) 在 Oracle Database10g 的時代,雖然沒有自動記憶體管理的功能,但是資料庫管理者可以 使用自動共用記憶體管理(Automatic Shared Memory Management-縮寫為 ASMM)的功能, 讓資料庫管理者僅需設定 SGA 總大小(SGA_TARGET)的值即可,其餘共用記憶體元件的大 小則自動依 Oracle 伺服器狀態自動決定,而且還可以動態地調整共用記憶體元件的大小。 至於自動記憶體管理與自動共用記憶體管理的差異,則在於自動記憶體管理可以同時自動管 理 SGA 與 PGA 的大小。而自動共用記憶體管理只能自動管理 SGA 的大小,不能管理 PGA 的大小。不過自 Oracle Database 9i 開始,資料庫管理者可以藉由設定 PGA 聚總目標 (PGA_AGGREGATE_TARGET)讓 PGA 的管理機制變成自動管理。所以在 Oracle Database 10g 只要啟用(Enable)自動共用記憶體管理與設定 PGA 聚總目標,便可以達到類似 Oracle Database 11g 自動記憶體管理的效果。 啟用自動共用記憶體管理,只需將 SGA_TARGET 的值設為大於 0 即可 。資料庫管理者可以 透過下列的步驟,啟用自動共用記憶體管理: 1.取得 SYSDBA 的權限。 2.如果是 Oracle Database 11g,需要先停用(Disable)自動記憶體管理。 SQL> SHOW PARAMETER target NAME TYPE VALUE ------------------------------------------ ---------------- ------------------------------ memory_max_target big integer 544M memory_target big integer 544M pga_aggregate_target big integer 0 sga_target big integer 0 SQL> ALTER SYSTEM SET memory_target=0; --停用自動記憶體管理 SQL> SHOW PARAMETER target NAME TYPE VALUE ------------------------------------------ ----------------------- ---------------------------- pga_aggregate_target big integer 0 sga_target big integer 0
  • 11. Chapter 3 – Oracle Instance Oracle Database Management Best Practice SQL> SHOW PARAMETER pool_size NAME TYPE VALUE ------------------------------------------ ----------------------- -------------------------- java_pool_size big integer 24M large_pool_size big integer 0 shared_pool_size big integer 64M streams_pool_size big integer 0 SQL> SHOW PARAMETER cache_size NAME TYPE VALUE ------------------------------------------ ---------------------- --------------------------- db_16k_cache_size big integer 0 db_2k_cache_size big integer 0 db_32k_cache_size big integer 0 db_4k_cache_size big integer 0 db_8k_cache_size big integer 0 db_cache_size big integer 48M db_keep_cache_size big integer 0 db_recycle_cache_size big integer 0 由以上範例可以得知目前自動共用記憶體管理的功能是停用,因為 SGA_TARGET 的值為 0。 而 SHARED POOL 與 JAVA POOL、DEFAULT BUFFER CACHE 的值為記載於參數檔的 設定。 3.設定 SGA_TARGET 為適當值。 SQL> SHOW PARAMETER sga NAME TYPE VALUE ---------------------------------------- ------------------------- ----------------- sga_max_size big integer 544M sga_target big integer 0 /*啟用自動共用記憶體管理時,注意sga_target必須小於等於sga_max_size 若sga_max_size為0,則需要先設定sga_max_size參數,才能設定sga_target參數。可是sga_ max_size為靜態參數,必須使用下面的指令才能設定。 ALTER SYSTEM SET sga_max_size=544M SCOPE=spfile。 並且重新啟動Oracle執行處理,才能生效。*/ SQL> ALTER SYSTEM SET sga_target=300M; SQL> SHOW PARAMETER sga NAME TYPE VALUE
  • 12. Chapter 3 – Oracle Instance Oracle Database Management Best Practice ---------------------------------------- ------------------------- ----------------- sga_max_size big integer 544M sga_target big integer 300M SQL> SHOW PARAMETER pool_size NAME TYPE VALUE ---------------------------------------- ------------------------ ----------------- java_pool_size big integer 0 large_pool_size big integer 0 shared_pool_size big integer 0 streams_pool_size big integer 0 SQL> SHOW PARAMETER cache_size NAME TYPE VALUE ---------------------------------------- ------------------ ----------------- db_16k_cache_size big integer 0 db_2k_cache_size big integer 0 db_32k_cache_size big integer 0 db_4k_cache_size big integer 0 db_8k_cache_size big integer 0 db_cache_size big integer 0 db_keep_cache_size big integer 0 db_recycle_cache_size big integer 0 由上面的範例結果來看,可以看到 SGA_TARGET 為 300M,而其他組成 SGA 的共用記憶體 元件都沒有明確設定其大小,則那些共用記憶體元件的大小則由 Oracle 伺服器依整體的狀態 來決定。 但是目前 SGA_TARGET 設定為 300M 到底夠不夠用?管理者可已由 V$ SGA_TARGET_ADVICE 得知,若加大 SGA_TARGET 的值是否有好處?反之若減少 SGA_TARGET 的值是否影響整體的效能? SQL> SELECT sga_size,sga_size_factor size_factor, 2> estd_db_time_factor time_factor,estd_physical_reads phy_reads 3> FROM v$sga_target_advice; SGA_SIZE SIZE_FACTOR TIME_FACTOR PHY_READS --------------------------- ------------------------ ------------------- --------------------- 300 1 1 12970 225 .75 1.0429 12970 375 1.25 1 12970
  • 13. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 450 1.5 .7786 9604 525 1.75 .7786 9604 600 2 .7786 9604 --如果有足夠的Free Memory SQL> SELECT * FROM v$sga_dynamic_free_memory; CURRENT_SIZE ---------------------- 255852544 --尚有244M的可用記憶體空間 SQL> ALTER SYSTEM SET sga_target=450M; --如果目前的Free Memory不足 SQL> SELECT * FROM v$sga_dynamic_free_memory; CURRENT_SIZE ---------------------- 0 /*沒有多餘的可用記憶體,因此必須同步增加sga_max_size2的值,但是sga_max_size為靜態 參數,必須先設定到參數檔,等執行處理重新啟動後,才會生效。*/ SQL> ALTER SYSTEM SET sga_max_size=450M SCOPE=spfile; SQL> ALTER SYSTEM SET sga_target=450M SCOPE=spfile; --重新啟動執行處理,讓新的sga_max_size與sga_target設定生效
  • 14. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 由上面的範例可以看到目前的 SGA_TARGET 為 300M,因為 SGA_SIZE_FACTOR 為 1。 同時可以得知,如果將 SGA_TARGET 增加為 450M,可以減少 3366 個實體讀取(由資料檔 將資料區塊讀到緩衝區快取的操作,這種型態的讀取數量越大,整體資料庫的效能越差,應 該盡量避免此種讀取型態)。這時資料庫管理者便可以考慮將 SGA_TARGET 設為 450M,以 減少實體讀取數量,進而提昇整體資料庫的效能。需要注意的地方是 SGA_TARGET 的值必 須小於 SGA_MAX_SIZE。 那為什麼不增加為 375M 或 600M 呢?首先增加到 375M 並沒有同步減少實體讀取量,這樣 只有浪費所增加的記憶體。然後增加為 600M 與增加到 450M 的效果一樣,那為何要多浪費 150M 的記憶體。所以依範例的結果來看,SGA_TARGET 增加為 450M 是最好的選擇。 如果資料庫管理者不想要直接查詢動態效能視觀圖(Dynamic Performance View),也可以透 過 EM(Enterprise Manager)的記憶體建議程式,得到相關的建議。
  • 15. Chapter 3 – Oracle Instance Oracle Database Management Best Practice
  • 16. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 如果資料庫管理者想要知道目前各個共用記憶體元件的大小,可以查詢 V$SGA_DYNAMIC_COMPONENTS 來得到相關資訊。 SQL> select component,current_size from v$sga_dynamic_components; COMPONENT CURRENT_SIZE ------------------------------------------------------ ---------------------- shared pool 121634816 large pool 4194304 java pool 12582912 streams pool 0 DEFAULT buffer cache 171966464 KEEP buffer cache 0 RECYCLE buffer cache 0 DEFAULT 2K buffer cache 0
  • 17. Chapter 3 – Oracle Instance Oracle Database Management Best Practice DEFAULT 4K buffer cache 0 DEFAULT 8K buffer cache 0 DEFAULT 16K buffer cache 0 DEFAULT 32K buffer cache 0 Shared IO Pool /*11g新增*/ 0 ASM Buffer Cache 0 在自動共用記憶體管理的機制下,Oracle 伺服器可以自動管理某些共用記憶體元件,但不是 所有的共用記憶體元件都可以被自動管理。資料庫管理者可由 V$SGA_INFO 中得知目前共用 記憶體元件的配置狀況及哪些共用記憶體元件可以自動管理。如果某個記憶體元件的 RESIZEABLE 欄位值為 YES,表示該共用記憶體元件可以自動管理。 ◎Oracle11g:SHARED POOL、LARGE POOL、JAVA POOL、STREAMS POOL、 DEFAULT BUFFER CACHE、SHARED IO POOL。 ◎Oracle10g:SHARED POOL、LARGE POOL、JAVA POOL、STREAMS POOL、 DEFAULT BUFFER CACHE。 SQL> SELECT * FROM v$sgainfo; NAME BYTES RESIZE ------------------------------------------------------ ----------------------- ------------ Fixed SGA Size 129962 No Redo Buffers 6373376 No Buffer Cache Size 188743680 Yes Shared Pool Size 104857600 Yes Large Pool Size 4194304 Yes Java Pool Size 12582912 Yes Streams Pool Size 0 Yes Shared IO Pool Size /*11g*/ 0 Yes Granule Size 4194304 No Maximum SGA Size 318054400 No Startup overhead in Shared Pool 46137344 No Free SGA Memory Available 0 系統整體區域(SGA)是由多種不同用途的共用記憶體元件所組成,不是每個共用記憶體元件都 可以自動管理,也有些共用記憶體元件自 Oracle 執行處理啓動後,便不能變更其空間的大小: Fixed SGA、Log Buffer、Result Cache(Oracle11 新增)。也有些是可以動態變更其空間的 大小,但必須是由資料庫管理者變更:KEEP BUFFER CACHE、RECYCLE BUFFER CACHE、DEFAULT 2K BUFFER CACHE、DEFAULT 4K BUFFER CACHE、DEFAULT
  • 18. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 8K BUFFER CACHE、DEFAULT 16K BUFFER CACHE、DEFAULT 32K BUFFER CACHE、ASM BUFFER CACHE。 因此當使用自動共用記憶體管理時,Oracle 伺服器會先扣除不能被自動管理的共用記憶體元 件後,將剩餘的共用記憶體空間依照目前 Oracle 伺服器的狀況,最適地將記憶體分配給 SHARED POOL、 LARGE POOL、JAVA POOL、STREAMS POOL、DEFAULT BUFFER CACHE、SHARED IO POOL(Oracle 11g 新增)。
  • 19. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3.1.3 動態系統整體區域(Dynamic SGA) 在 Oracle Database 9i 之前,如果 Oracle 執行處理已經啓動, 資料庫管理者想要改變任何 一種共用記憶體元件的大小,只能先修改參數檔(Parameter file)內容,將相關記憶體元件的 大小設定為所希望的大小,之後必須等待機會將 Oracle 執行處理重新啟動,這樣才能修改共 用記憶體元件的大小。 不過從 Oracle Database 9i 開始,藉由設定 SGA_MAX_SIZE 讓 SGA 的最大值不能超過此 值,資料庫管理者便可以動態變更某些共用記憶體的大小,而不需要將 Oracle 執行處理重新 啓動,這種功能稱做動態系統整體區域(Dynamic SGA)。那麼 Oracle 是怎樣做到動態調整某 些共用記憶體元件的大小呢?答案是 Granule。 Granule 是 Oracle Database 9i 開始使用的共用記憶體配置的單位,這種記憶體管理的技巧, 是將共享記憶體空間先切分為ㄧ塊塊的 Granule,每個 Granule 的大小是一樣的。然後再依每 個共用記憶體元件所需的大小,分配足夠個數的 Granule 給該共用記憶體元件,而且每個共 用記憶體元件被配置的 Granule 個數,一定要是整數個。Granule 的大小,則與 Oracle 版本、 作業系統及 SGA_MAX_SIZE 的設定值有關。 Granule Size:4M。當 SGA_MAX_SIZE<=1G(10g 之後)/128M(9i) Granule Size : 8M。當 SGA_MAX_SIZE>1G(10g 之後)/128M(9i) ,而且作業系統為 MicroSoft Windows 平台系列。 Granule Size : 16M。當 SGA_MAX_SIZE>1G(10g 之後)/128M(9i)。 不過需要注意的地方是動態 SGA 的功能僅表示共用記憶體空間可以動態變更大小,不代表 Oracle 伺服器能自動管理這些共用記憶體的大小。資料庫管理者可以藉由查詢 V$SGA_DYNAMIC_COMPONENTS 得知,哪些共用記憶體可以動態變更其大小及目前的大 小。 SQL> SELECT component,current_size,granule_size 2> FROM v$sga_dynamic_components; COMPONENT CURRENT_SIZE GRANULE_SIZE ------------------------------------------ ----------------------- ---------------------- shared pool 121634816 4194304 large pool 4194304 4194304
  • 20. Chapter 3 – Oracle Instance Oracle Database Management Best Practice java pool /*10g*/ 2582912 4194304 streams pool /*10g*/ 0 4194304 DEFAULT buffer cache 171966464 4194304 KEEP buffer cache 0 4194304 RECYCLE buffer cache 0 4194304 DEFAULT 2K buffer cache 0 4194304 DEFAULT 4K buffer cache 0 4194304 DEFAULT 8K buffer cache 0 4194304 DEFAULT 16K buffer cache 0 4194304 DEFAULT 32K buffer cache 0 4194304 Shared IO Pool /*11g*/ 0 4194304 ASM Buffer Cache /*10g*/ 0 4194304 既然不能由 Oracle 伺服器自動管理,那麼資料庫管理者必須自己管理。但是資料庫管理者可 以參考 Oracle 伺服器所提供的多種顧問(Advisor)建議,這些建議可由 V$SHARED_POOL_ADVICE、V$DB_CACHE_ADVICE、V$JAVA_POOL_ADVICE、 V$STREMS_POOL_ADVICE 查知。 SQL> SHOW PARAMETER statistics_level NAME TYPE VALUE ------------------------------- ----------- ------------------------------ statistics_level string TYPICAL /*若要啟動相關的顧問建議,則statistics_level的設定值,必須為typical或all。如果statistics_le vel的設定值為basic,則Oracle伺服器不會提供相關的建議。*/ SQL> DESC v$shared_pool_advice Name Null? Type ----------------------------------------------------------------- ----------- ---------------- SHARED_POOL_SIZE_FOR_ESTIMATE NUMBER SHARED_POOL_SIZE_FACTOR NUMBER ESTD_LC_SIZE NUMBER ESTD_LC_MEMORY_OBJECTS NUMBER ESTD_LC_TIME_SAVED NUMBER ESTD_LC_TIME_SAVED_FACTOR NUMBER ESTD_LC_LOAD_TIME NUMBER ESTD_LC_LOAD_TIME_FACTOR NUMBER ESTD_LC_MEMORY_OBJECT_HITS NUMBER SQL> SELECT shared_pool_size_for_estimate estd_size, 2> shared_pool_size_factor size_factor, 3> estd_lc_time_saved time_saved,
  • 21. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 4> estd_lc_time_saved_factor aved_factor 5> FROM v$shared_pool_advice; ESTD_SIZE SIZE_FACTOR TIME_SAVED SAVED_FACTOR ------------------ ----------------------- ---------------------- ------------------------- 60 1 3886 1 68 1.1333 3995 1.0280 76 1.2667 4230 1.0885 84 1.4 4908 1.2630 92 1.5333 5501 1.4156 100 1.6667 6230 1.6031 108 1.8 6230 1.6031 116 1.9333 6230 1.6031 124 2.0667 6230 1.6031 SQ> alter system set shared_pool_size=100M; 上面的範例是以 V$SHARED_POOL_ADVICE 為例子,可以得知目前的共用集區(Shared Pool)為 60M,因為其的 SHARED_POOL_SIZE_FACTOR 值為 1。也可以得知,如果將共 用集區的大小增為 100M 時,Oracle 伺服器的解析時間可以減少約 40%左右。因此如果有多 餘的共用記憶體,可以考慮增加共用集區的大小。 SQL> desc v$db_cache_advice Name Null? Type ----------------------------------------------------- -------- ---------------------------- ID NUMBER NAME VARCHAR2(20) BLOCK_SIZE NUMBER ADVICE_STATUS VARCHAR2(3) SIZE_FOR_ESTIMATE NUMBER SIZE_FACTOR NUMBER BUFFERS_FOR_ESTIMATE NUMBER ESTD_PHYSICAL_READ_FACTOR NUMBER ESTD_PHYSICAL_READS NUMBER ESTD_PHYSICAL_READ_TIME NUMBER ESTD_PCT_OF_DB_TIME_FOR_READS NUMBER ESTD_CLUSTER_READS NUMBER ESTD_CLUSTER_READ_TIME NUMBER SQL> SELECT size_for_estimate estd_size,size_factor size_factor, 2> estd_physical_read_factor estd_read_factor, 3> estd_physical_reads estd_reads
  • 22. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 4> FROM v$db_cache_advice 5> WHERE name='DEFAULT'; ESTD_SIZE SIZE_FACTOR ESTD_READ_FACTOR ESTD_READS ------------------- ---------------------- -------------------------------- ------------------- 16 .0889 1.4367 19020 32 .1778 1.224 16204 48 .2667 1.0928 14467 64 .3556 1 13239 80 .4444 1 13239 96 .5333 1 13239 112 .6222 1 13239 128 .7111 1 13239 144 .8 1 13239 160 .8889 1 13239 176 .9778 1 13239 180 1 1 13239 192 1.0667 1 13239 208 1.1556 1 13239 224 1.2444 1 13239 240 1.3333 1 13239 256 1.4222 1 13239 272 1.5111 1 13239 288 1.6 1 13239 304 1.6889 1 13239 320 1.7778 1 13239 SQL> ALTER SYSTEM SET db_cache_size=64M;
  • 23. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 上面的範例是以 V$DB_CACHE_ADVICE 為例子,可以得知目前的預設緩衝區快取 (DEFAULT CACHE BUFFER)為 180M,因為它的 SIZE_FACTOR 值為 1。也可以得知,如 果將預設緩衝區快取減為 64M 時,實體讀取的次數並不會因此而增加。這時資料庫管理者可 以將預設緩衝區快取空間縮小,並將多餘的共用記憶體分配給更需要記憶體的元件使用。
  • 24. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3.1.4 自動程式整體區域管理(Automatic PGA Management) 在 Oracle Database 9i 之前,每個伺服器處理作業(Server Process)所使用的程式整體區域 (Program Global Area)大小是由以下 4 個參數值所決定:SORT_AREA_SIZE、 HASH_JOIN_SIZE、CREATE_BITMAP_AREA_SIZE、MERGE_BITMAP_AREA_SIZE。 SORT_AREA_SIZE: 當進行排序操作(Sort Operation)時,每個排序操作所能使用的最大記 憶體空間,若超過此設定值,則該排序操作將使用暫時區段進行磁碟排序。預設值為 64K。 HASH_AREA_SIZE:當進行雜湊結合(Hash Join)時,所能使用的最大記憶體空間。預設值 為 128K。 CREATE_BITMAP_AREA_SIZE:當建立位元組索引(Bitmap Index)時,可以使用的記憶體 空間。若此設定值越大,則建立位元組索引的動作就越快完成。預設值為 8M。 MERGE_BITMAP_AREA_SIZE:當兩個位元組索引進行比對時,所使用的記憶體空間。此設 定值越大,則所需的比對時間就越短。預設值為 1M。 一個伺服器處理作業所擁有的 PGA 空間往往會隨著時間而成長,因為當伺服器處理作業會要 求更大的 PGA 空間來進行某些 SQL 敘述句,但是當 SQL 敘述句執行完畢後,這個 PGA 的 空間便由伺服器處理作業擁有,即使現在伺服器處理作業已經不需要這麼大的 PGA 空間,這 個 PGA 空間也不會縮減,只有在伺服器處理作業結束後,才會將該 PGA 所使用的記憶體還 給作業系統。
  • 25. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 當 PGA_AGGREGATE_TARGET 為 0 時,表示 PGA 的大小為*_AREA_SIZE 所決定。 SQL> CONNECT / AS SYSDBA --以sys身份,執行下面的範例 SQL> SHOW PARAMETER pga_aggregate_target NAME TYPE VALUE ------------------------------------------ ----------------------- --------------------------- pga_aggregate_target big integer 0 --當pga_aggregate_target為0,則pga的大小由下面4個參數決定 SQL> SHOW PARAMETER area_size NAME TYPE VALUE ------------------------------------------ ---------------------- ----------------------------- bitmap_merge_area_size integer 1048576 create_bitmap_area_size integer 8388608 hash_area_size integer 131072 sort_area_size integer 65536 workarea_size_policy string MANUAL --找出目前階段作業所使用的PGA大小 SQL> SELECT a.name,b.value 2> FROM v$statname a,v$sesstat b
  • 26. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3> WHERE a.statistic#=b.statistic# 4> AND (a.name LIKE 'session%ga memory%%' OR a.name LIKE '%direct temp%') 5> AND sid=(SELECT distinct sid FROM v$mystat); NAME VALUE ------------------------------------------------------------------ ---------- session uga memory 170876 session uga memory max 236340 session pga memory 473472 --目前使用量 session pga memory max 539008 --最大值 physical reads direct temporary tablespace 0 physical writes direct temporary tablespace 0 -- 建立一個測試表格 SQL> CREATE TABLE t1 AS SELECT * FROM dba_objects; --收集表格的統計資料 SQL> EXECUTE DBMS_STATS.GATHER_TABLE_STATS(‘SYS’,’T1’); --啟動自動追蹤觀察,並僅顯示所使用的資源數量 SQL> SET AUTOTRACE TRACEONLY STATISTICS; SQL> SELECT * FROM t1 ORDER BY 1; Statistics ---------------------------------------------------------- 12 recursive calls 265 db block gets 1018 consistent gets 3080 physical reads 0 redo size 3880633 bytes sent via SQL*Net to client 50932 bytes received via SQL*Net from client 4594 SQL*Net roundtrips to/from client 0 sorts (memory) 1 sorts (disk) --當sort_area_size=64K時,需要進行磁碟排序 68888 rows processed --將SORT_AREA_SIZE增加為10M SQL> ALTER SESSION SET sort_area_size=10240000; SQL> SELECT * FROM t1 ORDER BY 1; Statistics
  • 27. Chapter 3 – Oracle Instance Oracle Database Management Best Practice ---------------------------------------------------------- 10 recursive calls 9 db block gets 1018 consistent gets 1036 physical reads 0 redo size 3224976 bytes sent via SQL*Net to client 50932 bytes received via SQL*Net from client 4594 SQL*Net roundtrips to/from client 0 sorts (memory) 1 sorts (disk) --當sort_area_size=10M時,還是需要進行磁碟排序 68888 rows processed --繼續增加SORT_AERA_SIZE的值到64M SQL> ALTER SESSION SET sort_area_size=65536000; SQL> SELECT * FROM t1 ORDER BY 1; Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 1018 consistent gets 0 physical reads 0 redo size 3226404 bytes sent via SQL*Net to client 50932 bytes received via SQL*Net from client 4594 SQL*Net roundtrips to/from client 1 sorts (memory) --只需進行記憶體排序即可 0 sorts (disk) --當sort_area_size=64M時,不需要進行磁碟排序 68888 rows processed SQL> SET AUTOTRACE OFF --關閉自動追蹤 SQL> SELECT a.name,b.value 2> FROM v$statname a,v$sesstat b 3> WHERE a.statistic#=b.statistic# 4> AND (a.name LIKE 'session%ga memory%%' OR a.name LIKE '%direct temp%') 5> AND sid=(SELECT distinct sid FROM v$mystat); NAME VALUE ------------------------------------------------------------------ ---------- session uga memory 170876
  • 28. Chapter 3 – Oracle Instance Oracle Database Management Best Practice session uga memory max 9270372 session pga memory 473472 session pga memory max 9845120 --最大值 physical reads direct temporary tablespace 6373 physical writes direct temporary tablespace 6373 由上面的範例得知,當 SORT_AREA_SIZE 為 64K 或 10M 時,都必須進行磁碟排序(Disk Sort:需要將被排序的資料,先儲存在暫時區段中,之後分批進行排序。)。如果將 SORT_AREA_SIZE 增為 64M 時,這時便可以在 PGA 中完成排序,即所謂的記憶體排序 (Memory Sort),記憶體排序的速度ㄧ定比磁碟排序的速度快。但也看到階段作業所使用的最 大 PGA 記憶體(SESSION PGA MEMORY MAX)的值由 539008 增加為 9845120,約為 9.4M。如果同時有 500 個階段作業進行同樣的 SQL 敘述句,那麼所有的 PGA 總和為 4.7G(9.4M*500),若加上 SGA 所使用的記憶體空間(假設為 2G),則此 Oracle 伺服器一共 消耗作業系統約 6.7G 的記憶體。如果這台伺服器的實體記憶體只有 4G,作業系統只好使用 虛擬記憶體(Virtual Memory)的機制來提供 Oracle 伺服器所需的記憶體。虛擬記憶體是使用 磁碟空間來模擬記憶體(UNIX 平台使用置換空間(Swap Space),Windows 平台使用分頁檔 (Pagefile)),這樣雖然可以提供更大的記憶體空間,但也會增加存取的時間,因為磁碟機的速 度遠慢於記憶體。所以這樣的 PGA 管理方式可能會造成記憶體不足的情況,進而導致 Oracle 伺服器的效能下滑。 但是這個問題不會馬上浮現,例如目前只有 100 個階段作業,即便每個階段作業需要 9.4M 的 PGA 空間,總共只需要 940M 的記憶體。加上 SGA(假設為 2G,此 Oracle 伺服器使用約 3G 的記憶體,不過因為作業系統有 4G 的實體記憶體,所以還不會出現使用虛擬記憶體的情 況。但隨著階段作業個數的增加,所有階段作業的 PGA 總和也逐漸地增加,一但 SGA 加 PGA 的總和大於實體記憶體後,作業系統便會開始使用虛擬記憶體。如此 Oracle 執行處理也 難免會使用到虛擬記憶體,進而造成 Oracle 伺服器的效能變差。為了避免使用虛擬記憶體所 帶來的效能問題,資料庫管理者可以犧牲個別的階段作業的排序效能,將*_AREA_SIZE 設定 值縮小,讓階段作業所能配置的 PGA 空間減少。這樣會造成階段作業進行排序時,因為使用 磁碟排序而造成排序時間增長。但也可以減少作業系統因實體記憶體不足而使用到虛擬記憶 體的可能性。 從 Oracle Database 9i 開始,管理者可以藉由將設定 PGA_AGGREGATE_TARGET(可以由 10M 到 4000G),啓用 PGA 自動管理。當啟用 PGA 自動管理後,每個階段作業可以使用的 最大 PGA 空間為 5%*PGA_AGGREGATE_TARGET。若為平行操作(Parallel Operation)最 大可達 30%*PGA_AGGREGATE_TARGET。不過 PGA 自動管理最重要的特點在於當每次
  • 29. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 排序動作完成後,所配置的 PGA 空間將會回收,不再繼續保留給伺服器處理作業。而 Oracle 伺服器盡量將 PGA 總和維持在 PGA_AGGREGATE_TARGET 設定值之下,然而還是有些記 憶體是不可回收的(例如:每個階段作業的 PGA 空間至少需要 250K),PGA 自動管理所帶來 的好處是 Oracle 伺服器所使用的記憶體,可以控制在一定的範圍內。只要不超過實體記憶體, 便不會使用虛擬記憶體的問題。不過 PGA 自動管理所帶來的副作用,便是單一階段作業的排 序效能可能受到影響。 --啟用PGA自動管理,只要將pga_aggregate_target設定即可 SQL> ALTER SYSTEM SET pga_aggregate_target=100M; SQL> SHOW PARAMETER pga_aggregate_target NAME TYPE VALUE ------------------------------------------ ----------------------- --------------------------- pga_aggregate_target big integer 100M --當pga_aggregate_target大於0,則workarea_size_policy自動設為AUTO SQL> SHOW PARAMETER workarea_size_policy NAME TYPE VALUE ------------------------------------------ ---------------------- ----------------------------- workarea_size_policy string AUTO 啟用 PGA 自動管理後,資料庫管理者可以由 V$PGA_TARGET_ADVICE 得知,目前的 PGA_AGGREGATE_TARGET 是否足夠。 SQL> select pga_target_for_estimate pga_target,pga_target_factor size_factor,estd_time, estd_pga_cache_hit_percentage hitratio from v$pga_target_advice; PGA_TARGET SIZE_FACTOR ESTD_TIME HITRATIO ------------------- ---------------------- ----------------------- ---------- 13107200 .125 5029 48 26214400 .25 5029 48 52428800 .5 5029 48 78643200 .75 5029 48 104857600 1 3002 80 125829120 1.2 3002 80 146800640 1.4 3002 80 167772160 1.6 3002 80 188743680 1.8 3002 80 209715200 2 3002 80 314572800 3 2390 100 419430400 4 2390 100 629145600 6 2390 100
  • 30. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 838860800 8 2390 100
  • 31. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 由上面的範例可以知道,目前的 PGA_AGGREGATE_TARGET 設為 100M,因為 PGA_TARGET_FACTOR 為 1。同時可以知道如果 PGA_AGGREGATE_TARGET 增為 300M,將減少排序時間達 20%,使用記憶體排序的比率也可達到 100%。若減少 PGA_AGGREGATE_TARGET 為 75M,將導致排序時間增加為 167%,而記憶體排序的比 率也將降為 48%。所以如果還有多餘的實體記憶體可供使用,管理者應該考慮增加 PGA_AGGREGATE_TARGET 的值。不然至少不能再減少 PGA_AGGREGATE_TARGET 的 值了。
  • 32. Chapter 3 – Oracle Instance Oracle Database Management Best Practice
  • 33. Chapter 3 – Oracle Instance Oracle Database Management Best Practice
  • 34. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3.2 緩衝區快取(Buffer Cache) 當伺服器作業處理(Server Process)執行執行計畫時,利用緩衝區快取(Buffer Cache)將由資 料檔讀入的資料區塊(data block)快取起來。當執行其他的 SQL 敘述句時,如果需要相同的 資料區塊,便可以直接由緩衝區快取讀到所需的資料區塊,這種讀取模式稱作邏輯讀取 (Logical Read)。主要是利用記憶體的存取速度遠快過於磁碟機的優勢,將實體讀取轉換成邏 輯讀取。因此即便是 I/O 的總數量不變,但是整體 I/O 的時間卻可以大幅下降,如此便可以 縮短 SQL 敘述句的反應時間。 3.2.1 管理緩衝區快取 緩衝區快取用來存放伺服器處理作業由資料檔所讀入的資料區塊,因此緩衝區快取邏輯上被 切割為許多個緩衝,每個緩衝的大小與資料區塊的大小一致。因此緩衝(Buffer)依其內容與資 料檔的資料區塊是否一致,而分為下列幾類狀態: 可用緩衝(Free Buffer)/未使用緩衝(Unused Buffer) 目前此緩衝並沒有任何資料。這種情況並不常見,通常是在執行處理剛啓動或緩衝區快取的 空間剛被增加,才會有可能看到。資料庫管理者也可以使用 ALTER SYSTEM FLUSH BUFFER_CACHE 的指令,將緩衝區快取的緩衝內容都清空,因此所有的緩衝都變成此種型 態。所以這個指令不適合在正式環境使用,因為沒有任何效能上的好處,反而造成更多的實 體 I/O,增加資料庫的 I/O 負擔。這個指令主要用在測試環境,在每次測試前清除前次測試所 帶來的緩衝快取,確保每次測試的環境一致。 乾淨緩衝(Clean Buffer) 目前此緩衝的內容與資料檔的資料區塊一致。這種情況有可能是此緩衝的內容剛被伺服器處 理作業由資料檔中讀進,而且緩衝的內容還沒有被改變。也可能剛剛這個緩衝還是髒緩衝, 可是現在已經被 DBWR 將緩衝內容寫到資料檔的資料區塊,因此緩衝的狀態就變成乾淨。 阻止的緩衝(Pinned Buffer) 目前此緩衝的內容正在被某個伺服器處理作業(Server Process)改變,因此不能被其他的伺服 器處理作業讀取或異動。
  • 35. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 髒緩衝(Dirty Buffer) 目前此緩衝的內容與資料檔資料區塊的內容不一致,因為伺服器處理作業已經改變緩衝的內 容。
  • 36. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 緩衝區快取是由下列的多個子緩衝快取空間所組成的: 1.Default Buffer Cache:DB_CACHE_SIZE 2.Keep Buffer Cache:DB_KEEP_CACHE_SIZE 3.Recycle Buffer Cache:DB_RECYCLE_CACHE_SIZE 4.Non-Standard Block Buffer Cache:DB_nK_CACHE_SIZE(n=2/4/8/16/32) 3.2.2 Least Recently Use 演算法 緩衝區快取通常已經是整個 SGA 佔最大比例的一塊空間,不過再怎麼大的緩衝區快取,與資 料庫相較下還是不夠大。同時伺服器處理作業(Server Process)在進行任何的資料操作(查詢 或異動)前,該操作所需的資料必須先被讀到緩衝區快取,才能進行資料操作。因此緩衝的內 容勢必將有置換的情況發生,因為緩衝的數量遠小於資料區塊的數量。那麼 Oracle 伺服器如 何決定哪些緩衝的內容將被取代,而哪些緩衝的內容不需要被取代? Oracle 伺服器採用的是 LRU(Least Recent Used)機制,依每個緩衝的內容最近被存取的時 間及被存取的次數(Touch Count),排成一個串列(List),稱為 LRU 串列。這個串列有兩個端 點,一個端點稱為 MRU 端(Most Recently Uesd),越靠近 MRU 端的緩衝,表示其內容最近 才被存取且存取次數相對較多。另一個頭端為 LRU 端(Least Recently Used),越靠近 LRU 端的緩衝,表示其內容越久未被存取且存取次數相對較少。然而 LRU 串列的演算法經過長久
  • 37. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 的演進,發展出下列幾種:Standard LRU 演算法、Modified LRU 演算法與 Touch Count LRU 演算法。 標準的 LRU 演算法(Standard LRU Algorithm) 當伺服器處理作業發現它所需要的資料區塊,目前不存在於緩衝區塊快取,因此需要將那些 資料區塊由資料檔讀到緩衝區快取時,便開始由 LRU 串列的 LRU 端,開始尋找狀態為可用 或乾淨的緩衝。找到足夠的可用或乾淨的緩衝後,伺服器處理作業將資料區塊的內容讀到那 些緩衝之中,然後才進行後續的資料操作。而這些緩衝因為是最近被存取的緩衝,因此緩衝 在 LRU 串列的位置也被移到 MRU 端。因此 LRU 串列的其他緩衝就向 LRU 端遞移。 這種資料讀取的方式稱為實體讀取(Physical Read),需要消耗 I/O 頻寬與較長的讀取時間。 如果伺服器處理作業發現所需要的資料區塊已經存在於緩衝區快取的某些緩衝中,便直接使 用這些緩衝的內容進行資料操作。這種資料讀取的方式稱為邏輯讀取(Logical Read),不須消 耗 I/O 頻寬且讀取時間較短。當然這些緩衝的位置也被移到 LRU 串列的 MRU 端。 缺點:當對大型的表格(Table)進行全表格掃描(Full Table Scan)存取時,整個表格的資料區 塊需要讀到緩衝區快取。因為需要大量的緩衝,所以導致可用或乾淨緩衝的內容被置換。若 未使用或乾淨緩衝的個數不足時,將造成許多髒緩衝被寫回資料檔,將緩衝狀態變成乾淨後, 才能提供足夠的緩衝數量。然而通常使用全表格掃描所存取的資料區塊,被重複使用的機率 相當小。而之前被置換的資料區塊內容,反而更有可能被反覆使用。因此標準的 LRU 演算法 在遇到全表格掃描時,反而會造成更多的實體讀取,造成資料庫的效能因過多的實體 I/O 而 下降。
  • 38. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 修改過的 LRU 演算法(Modified LRU Algorithm) 為解決標準的 LRU 演算法在處理全表格掃描所發生的問題,Oracle 公司對標準的 LRU 演算 法進行修改。Oracle Database 7 開始使用這種修改過的 LRU 演算法,當伺服器處理作業對 某個表格進行全表格掃描存取時,會根據表格的資料區塊數量與參數檔的 cache_table_threshold 參數值進行比較,如果表格的資料區塊數量小於 cache_table_threshold 參數值,則這些資料區塊讀到緩衝區快取後,它們將被放置在 LRU 串列的 MRU 端。因為對小型表格進行全表格掃描存取是比較有效率且常見的方式,所以藉由 設定 cache_table_threshold 參數來界定何者危大型表格。若為小型表格則如同標準的 LRU 演算法一樣,將區塊位置放在 MRU 端。但若表格的資料區塊數量大於 cache_table_threshold 參數值,讀入的區塊則放在 LRU 端。 此外還有一個隱藏參數_small_table_threshold 也會影響全表格掃描存取時,表格的資料區塊 是否會放在 LRU 串列的 MRU 端。當表格的資料區塊數量小於_small_table_threshold 時, 這些經由全表格掃描讀入的表格區塊將放在 LRU 串列的 MRU 端。所以修改過的 LRU 演算法 便可以解決標準的 LRU 演算法在遇到全表格掃描存取所發生的問題。 缺點:如果使用索引範圍掃描存取表格,而需要讀取的索引樹葉區塊數量相當多。因為所讀 取的區塊為索引的樹葉區塊,同時並不是全表格掃描存取,這時將出現類似標準的 LRU 演算 法遇到全表格掃描時的問題。只是對象換成大量的索引樹葉區塊。 多個緩衝池機制(Multiple Buffer Pool) 為解決讀取大量索引樹葉區塊所發生的問題,Oracle 公司在 Oracle Database 8 時提出多個 緩衝池的架構。讓資料庫管理者最多可以將緩衝區快取分割為三部份:保存池(Keep Pool 使 用 DB_KEEP_POOL_SIZE 參數設定其大小)、回收池(Recycle Pool 使用 DB_RECYCLE_POOL_SIZE 參數設定其大小)及預設池(Default Pool 使用 DB_CACHE_SIZE 參數設定其大小)。每個緩衝池至少由一個工作集管理(Working set),每 個工作集由一個 LRU 串列與檢查點串列(Checkpoint Queue List)組成。所以如果其中一個 緩衝池發生緩衝內容置換的情況,其他的緩衝池並不會受到影響。 因此資料庫管理者可以將常用的資料區塊放在保存池,但要注意不要將太多的資料區塊放在 保存池中,因為需要放入保存池的資料區塊數量大於保存池的緩衝數量時,還是會使用 LRU 演算法進行緩衝內容的置換。
  • 39. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 可以將那些 SQL 敘述句執行完畢後,便不會再用到的資料區塊,放在回收池中。但不要讓回 收池太小,而造成 SQL 敘述句還未執行完畢,所需的資料區塊又因為回收池太小而需要再次 由資料檔讀到回收池中。 至於預設池是用來放置那些未明確指定使用保存池或回收池的資料區塊。 當資料區塊被讀取時,將依照資料區塊所屬的區段(Segment)的 storage 參數所指定的緩衝池, 決定將資料區塊讀到哪個緩衝池。以下是相關的指令範例: --使用BUFFER_POOL參數設定區段的資料區塊所屬的緩衝池, --若沒有明確指定,則預設使用預設池(default) --CREATE TABLE abc (a NUMBER) STORAGE (BUFFER_POOL {default|keep|recycle}) --CREATE INDEX abc_idx ON abc(a) STORAGE (BUFFER_POOL {default|keep|recycle}) --也可以在建立區段後,更改資料區塊所使用的緩衝池 --ALTER TABLE abc STORAGE (BUFFER_POOL keep) --ALTER INDEX abc_idx STORAGE(BUFFER_POOL recycle)
  • 40. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 所以資料庫管理者可以將索引的資料區設定存放在回收池中,因此當對一個大的索引進行範 圍掃描時,被讀取的索引樹葉區塊將被放到回收池中。即便造成回收池中的緩衝發生內容置 換的情況,也不會影響到保存池或預設池的資料區塊,這樣便可以解決修改過的 LRU 演算法 在讀取大量索引樹葉區塊所遇到的問題。 使用計數 LRU 演算法(Touch-Count LRU Algorithm) 從 Oracle Database 8i 開始,Oracle 資料庫使用 Touch-Count LRU 演算法取代之前使用的 修改的 LRU 演算法。新演算法的基本精神是每個資料區塊是否能被保留在緩衝區快取中,必 須依其被存取的次數與被存取的時間為依據,而不再只使用依存取時間為基準。因此現在的 LRU 串列被分成兩部份:一部份稱做熱區(Hot region),在熱區的資料區塊,稱做熱區塊。另 一部份則稱做冷區(Cold region),在冷區的資料區塊,稱做冷區塊。基本上熱區與冷區的大 小相當。不過兩者的比率可以透過隱藏參數_db_percent_hot_default 來調整。 當資料區塊被讀到緩衝區快取時,它將被放在熱區與冷區的中間,稱做中間點插入(Midpoint Insertion),實際上所插入的位置屬於熱區的一部份。此後資料區塊將依其被存取的次數,來 決定未來資料區塊的位置,是放在 LRU 串列的 MRU 端(持續在熱區)或逐漸向 LRU 端移動(進 入冷區)。 理論上當資料區塊每被存取一次,其使用計數(touch count)就會加一。然而使用計數 LRU 演 算法並不是如此,因為有時資料區塊會在短時間內被多次存取,但過了這段時間後,卻不再 使用該資料區塊。因此如果每存取一次就增加一次使用計數,可能導致誤判。Oracle 資料庫 採取在一段時間區間,不管資料區塊被存取幾次,其使用計數僅增加一的方式來因應這種可 能的問題。這個時間區間預設為 3 秒鐘,資料庫管理者可以用_db_aging_touch_time 來調整 區間長度。除外資料區塊的使用計數增加與資料區塊在 LRU 串列的位置是無關的,使用計數 表示資料的熱門程度,在 LRU 串列的位置決定被置換內容的優先順序。 F 12 D 0 F 0 D 2 F 2 P 0 F 1 P 10 F 1 F 15 D 8 D 10 LRU ListMRU End LRU End Hot Region Cold Region Midpoint
  • 41. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 資料區塊位置的移動 當伺服器處理作業在 LRU 串列中尋找可用或乾淨的緩衝時,或 DBWR 在 LRU 串列中尋找髒 緩衝時。如果發現到某個資料區塊的使用計數大於 2 的時候,則將該區塊的位置移動到 LRU 串列的 MRU 端,並將其使用計數設為 0。若發現乾淨緩衝的資料區塊的使用計數小於 2,伺 服器處理作業便選擇該緩衝當做未來讀入資料區塊的緩衝。可以藉由設定 _db_aging_hot_criteria 參數調整此使用計數大小。 當某個資料區塊被移到 LRU 串列的 MRU 端或一個新的資料區塊被新增到中間點時,至少都 會造成一個資料區塊由熱區被擠到冷區。若資料區塊由熱區移到冷區時,其使用計數將被設 定為 1,不論原來的使用計數為何。資料庫管理者可以藉由_db_aging_cool_count 調整當資 料區塊由熱區移到冷區時,使用計數的設定值。 因此可以得知使用計數 LRU 演算法,除考慮資料區塊的存取時間順序外,還考慮資料區塊的 存取次數,來決定資料區塊是否可以繼續留在緩衝區快取。讓目前保留在緩衝區快取的資料 區塊,一定是最近而且最常使用的(recently,frequent used)資料區塊。
  • 42. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 3.3 共用集區(Shared pool) 當一個 SQL 敘述句由使用者處理作業(User Process)傳遞到伺服器作業處理(Server Process) 時,伺服器作業處理必須先將該 SQL 敘述句解析為執行計畫,並將執行計畫儲存到共用集區 的程式庫快取(Library Cache)後,接著才能使用該執行計畫進行後續的操作。為何要先將執 行計畫先存放在共用集區後,才能繼續執行?因為當下次使用者執行相同的 SQL 敘述句時, 便可以直接由程式庫快取取得之前產生的執行計畫,就不需要再次硬解析(Hard Parse),而只 需要進行軟解析(Soft Parse)即可。這樣的機制可以大幅地減少硬解析的次數,對提昇 Oracle 伺服器的效能有相當大的幫助。 3.3.1 結果集快取(Result Cache) 從 Oracle Database 11g 開始,Oracle 伺服器更進一步將 SQL 敘述句的結果,直接快取存 放在 Result Cache。因此當下次執行相同的 SQL 敘述句時,就不需要再次執行,直接將存 放在 Result Cache 的結果,直接回傳給使用者即可,如此可以得到更短的反應時間。同時 Oracle Database 11g 會自動偵測結果集的正確性,如果相關資料表的內容有變動,將會將 該結果集設定為失效,下次執行相同的 SQL 敘述句時,會重新執行該敘述句產生最新的結果 集並再次快取到 Result Cache 中。 結果集快取參數 RESULT_CACHE_MODE RESULT_CACHE_MODE 決定 SQL 敘述句的結果是否要被快取到 Result Cache 中,如果 設定為 MANUAL,查詢指令必須加上 RESULT_CACHE 的 HINT,其執行結果才能被快取。 反之為設定為 FORCE,則執行結果會自動被快取,除非加上 NO_RESULT_CACHE 才會不 使用被快取。而 RESULT_CACHE_MODE 設定為 AUTO 時,則讓 Oracle 伺服器自動判斷是 否要將其執行結果快取。
  • 43. Chapter 3 – Oracle Instance Oracle Database Management Best Practice RESULT_CACHE_MAX_SIZE RESULT_CACHE_MAX_SIZE 設定結果集快取最大可以使用的大小,如果將其設為 0 則為 關閉結果集快取的功能。若明確設定此參數值時,請注意此參數不能大於共用集區大小的 75%。 若沒有明確設定此值則依下列機制設定︰ • 如果有設定 MEMORY_TARGET 參數值,則 RESULT_CACHE_MAX_SIZE 為 0.25%*MEMORY_TARGET。 • 如果沒有設定 MEMORY_TARGET 參數值,但有設定 SGA_TARGET,則 RESULT_CACHE_MAX_SIZE 為 0.5%*SGA_TARGET。 • 如果 MEMORY_TARGET 與 SGA_TARGET 都沒有設定,則 RESULT_CACHE_MAX_SIZE 為 1.0%*SHARED_POOL_SIZE。 建立相關測試環境 SQL> CONNECT / AS sysdba --以sys身份登入資料庫 --建立角色plustrace,將plustrace角色授權給新建的使用者,讓他可以使用autotrace的功能 --用來觀察結果集快取操作狀況 SQL> @$ORACLE_HOME/sqlplus/admin/plustrce.sql --建立一個測試的資料庫使用者,因為在11.1.0.7時,結果集快取機制不能使用在sys的階段作業 --在11.1.0.8以後,結果集快取的功能也可以用在sys所建立的階段作業上 SQL> CREATE USER frank IDENTIFIED BY oracle 2 DEFAULT TBALESPACE users 3 QUOTA UNLIMITED ON users; SQL> GRANT CONNECT,RESOURCE,PLUSTRACE TO frank; SQL> CREATE TABLE frank.big1 AS SELECT * FROM dba_objects; --建立測試表格 SQL> execute dbms_stats.gather_table_stats('FRANK','BIG1'); --收集表格的統計資料 SQL> show parameter result_cache_mode NAME TYPE VALUE
  • 44. Chapter 3 – Oracle Instance Oracle Database Management Best Practice ------------------------------- ----------- ------------------------------ result_cache_mode string MANUAL --查詢敘述句不會自動產生與使用結果集快取
  • 45. Chapter 3 – Oracle Instance Oracle Database Management Best Practice
  • 46. Chapter 3 – Oracle Instance Oracle Database Management Best Practice
  • 47. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 可以使用 V$RESULT_CACHE_DEPENDENCY 的內容,查知與哪些表格有被快取。 如果需要察看目前的 Result Cache 的狀態,可以透過 V$RESULT_CACHE_STATISTICS 或 DBMS_RESULT_CACHE.MEMORY_REPORT 得知。
  • 48. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 結果集快取的有效性由 Oracle 伺服器自動維護,例如當結果集快取的相關表格內容被異動後, 已快取的結果集狀態將被設定為失效(Invalid),同時與結果集相關的相依關係也將被移除。而 且最佳化處理程式並不會使用一個失效的結果集快取,所以不用擔心資料的正確性。
  • 49. Chapter 3 – Oracle Instance Oracle Database Management Best Practice 結果集快取可以大幅降低 SQL 查詢敘述句所需要的反應時間,尤其當記憶體成本越來越低的 現在,相信未來將會有更多的功能,會使用類似的技巧,來減少 SQL 敘述句的反應時間。 不過結果集快取並不適合用在線上交易處理(OLTP)型態的資料庫,因為執行結果快取後,如 果相關的表格內容被異動,結果集的狀態將自動變成失效,而最佳化處理程式無法使用失效 的結果集。而資料倉儲型態的資料庫不常變動資料內容,所以結果集的有效期間可以維持的 較久,因此結果集快取比較適合用在資料倉儲型態的資料庫。 結論 系統整體區域(System Global Area)是執行處理中最重要的元件,Oracle 伺服器的效能與系 統整體區域的管理息息相關。緩衝區快取與共用集區則是 SGA 最重要的兩個元件,經過第二 章與本章的說明後,資料庫管理者應該能夠了解緩衝區快取與共用集區的用途與基本管理, 也能夠分辨自動記憶體管理與自動共用記憶體管理。