一直都想總結一下oracle內存調整方面的知識,最近正好優化一個數據庫內存參數,查找一些資料並且google很多下。現在記錄下來,做下備份。
一、概述:
oracle 的內存可以按照共享和私有的角度分為系統全局區和進程全局區,也就是 SGA和 PGA(process global area or private global area)。對於 SGA 區域內的內存來說,是共享的全局的,在 UNIX 上,必須為 oracle 設置共享內存段(可以是一個或者多個),因為 oracle 在UNIX 上是多進程;而在 WINDOWS 上 oracle 是單進程(多個線程),所以不用設置共享內存段。PGA 是屬於進程(線程)私有的區域。在 oracle 使用共享服務器模式下(MTS),PGA中的一部分,也就是 UGA 會被放入共享內存 large_pool_size 中。
發張圖oracle內存架構組成,按照圖上面的顯示可以一目了然關鍵的參數和參數名稱:
對於 SGA 部分,我們通過 sqlplus 中查詢可以看到:
SQL> select * from v$sga;
NAME VALUE
---------- --------------------
Fixed Size 454032
Variable Size 109051904
Database Buffers 385875968
Redo Buffers 667648Fixed Size:
oracle 的不同平台和不同版本下可能不一樣,但對於確定環境是一個固定的值,裡面存儲了 SGA 各部分組件的信息,可以看作引導建立 SGA 的區域。
Variable Size :
包含了 shared_pool_size、java_pool_size、large_pool_size 等內存設置
Database Buffers :
指數 據緩 沖區:
在 8i 中包 含 db_block_buffer*db_block_size、buffer_pool_keep、buffer_pool_recycle 三 部 分內 存 。
在 9i 中 包 含 db_cache_size 、db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size。
Redo Buffers :
指日志緩沖區,log_buffer。在這裡要額外說明一點的是,對於 v$parameter、v$sgastat、v$sga 查詢值可能不一樣。v$parameter 裡面的值,是指用戶在初
始化參數文件裡面設置的值,v$sgastat 是 oracle 實際分配的日志緩沖區大小(因為緩沖區的分配值實際上是離散的,也不是以 block 為最小單位進行分配的),
v$sga 裡面查詢的值,是在 oracle 分配了日志緩沖區後,為了保護日志緩沖區,設置了一些保護頁,通常我們會發現保護頁大小大約是 11k(不同環境可能不一樣)。
對於日志緩沖區的大小設置,通常我覺得沒有過多的建議,因為參考 LGWR 寫的觸發條件之後,我們會發現通常超過 3M 意義不是很大。作為一個正式系統,
可能考慮先設置這部分為 log_buffer=3—5M 大小,然後針對具體情況再調整。
log_buffer是Redo log的buffer。
因此在這裡必須要了解Redo Log的觸發事件(LGWR)
1、當redo log buffer的容量達到1/3
2、設定的寫redo log時間間隔到達,一般為3秒鐘。
3、redo log buffer中重做日志容量到達1M
4、在DBWn將緩沖區中的數據寫入到數據文件之前
5、每一次commit--提交事務。
上面的結論可以換句話說
1、log_buffer中的內容滿1/3,緩存刷新一次。
2、最長間隔3秒鐘,緩存刷新一次
3、log_buffer中的數據到達1M,緩存刷新一次。
4、每次提交一個“事務”,緩存刷新一次
對於大緩沖池的設置,假如不使用 MTS,建議在 20—30M 足夠了。這部分主要用來保存並行查詢時候的一些信息,還有就是 RMAN 在備份的時候可能會使用到。
如果設置了MTS,則由於 UGA 部分要移入這裡,則需要具體根據 server process 數量和相關會話內存參數的設置來綜合考慮這部分大小的設置。
假如數據庫沒有使用 JAVA,我們通常認為保留 10—20M 大小足夠。事實上可以更少,甚至最少只需要 32k,但具體跟安裝數據庫的時候的組件相關(比如 http server)。
Shared_pool_size的開銷通常應該維持在300M 以內。除非系統使用了大量的存儲過程、函數、包,
比如 oracle erp 這樣的應用,可能會達到 500M 甚至更高。於是我們假定一個 1G 內存的系統,可能考慮
設置該參數為 100M,2G 的系統考慮設置為 150M,8G 的系統可以考慮設置為 200—300M
SGA區包括了各種緩沖區和內存池,而大部分都可以通過特定的參數來指定他們的大小。但是,作為一個昂貴的資源,一個系統的物理內存大小是有限。
盡管對於CPU的內存尋址來說,是無需關系實際的物理內存大小的(關於這一點,後面會做詳細的介紹),但是過多的使用虛擬內存導致page in/out,
會大大影響系統的性能,甚至可能會導致系統crash。所以需要有一個參數來控制SGA使用虛擬內存的最大大小,這個參數就是SGA_MAX_SIZE。當實例啟動後,
各個內存區只分配實例所需要的最小大小,在隨後的運行過程中,再根據需要擴展他們的大小,而他們的總和大小受到了SGA_MAX_SIZE的限制。
對於OLTP系統,參考:
系統內存
SGA_MAX_SIZE值
1G 400-500M
2G 1G
4G 2500M
8G 5G
oracle實例啟動時,會只載入各個內存區最小的大小。而其他SGA內存只作為虛擬內存分配,
只有當進程touch到相應的頁時,才會置換到物理內存中。但我們也許希望實例一啟動後,所有SGA
都分配到物理內存。這時就可以通過設置PRE_PAGE_SGA參數來達到目的了。這個參數的默認值
為FALSE,即不將全部SGA置入物理內存中。當設置為TRUE時,實例啟動會將全部SGA置入物理
內存中。它可以使實例啟動達到它的最大性能狀態,但是,啟動時間也會更長(因為為了使所有SGA
都置入物理內存中,oracle進程需要touch所有的SGA頁)。