一直都想總結一下oracle內存調整方面的知識,最近正好優化一個數據庫內存參數,查找一些資料而且google不少下。如今記錄下來,作下備份。php
1、概述:
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 667648
Fixed 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(不一樣環境可能不同)。
2、SGA內參數及設置:
2.1 Log_buffer
對於日誌緩衝區的大小設置,一般我以爲沒有過多的建議,由於參考 LGWR 寫的觸發條件以後,咱們會發現一般超過 3M 意義不是很大。做爲一個正式系統,
可能考慮先設置這部分爲 log_buffer=3—5M 大小,而後針對具體狀況再調整。
log_buffer是Redo log的buffer。
所以在這裏必需要了解Redo Log的觸發事件(LGWR)
一、當redo log buffer的容量達到1/3
二、設定的寫redo log時間間隔到達,通常爲3秒鐘。
三、redo log buffer中重作日誌容量到達1M
一、log_buffer中的內容滿1/3,緩存刷新一次。
三、log_buffer中的數據到達1M,緩存刷新一次。
2.2 Large_pool_size
對於大緩衝池的設置,假如不使用 MTS,建議在 20—30M 足夠了。這部分主要用來保存並行查詢時候的一些信息,還有就是 RMAN 在備份的時候可能會使用到。
若是設置了MTS,則因爲 UGA 部分要移入這裏,則須要具體根據
server process 數量和相關會話內存參數的設置來綜合考慮這部分大小的設置。
2.3 Java_pool_size
假如數據庫沒有使用
JAVA,咱們一般認爲保留 10—20M 大小足夠。事實上能夠更少,甚至最少只須要 32k,但具體跟
安裝數據庫的時候的組件相關(好比 http server)。
2.4 Shared_pool_size
Shared_pool_size
的開銷一般應該維持在
300M 之內。除非系統使用了大量的存儲過程、函數、包,
好比 oracle erp 這樣的應用,
可
能會達到 500M 甚至更高。
因而咱們假定一個 1G 內存的系統,可能考慮
設置該參數爲 100M,
2G 的系統考慮設置爲 150M,8G 的
系統能夠考慮設置爲 200—300M
2.5SGA_MAX_SIZE
SGA區包括了各類緩衝區和內存池,而大部分均可以經過特定的參數來指定他們的大小。可是,做爲一個昂貴的資源,一個系統的物理內存大小是有限。
儘管對於CPU的內存尋址來講,是無需關係實際的物理內存大小的(關於這一點,後面會作詳細的介紹),可是過多的使用虛擬內存致使page in/out,
會大大影響系統的性能,甚至可能會致使系統crash。因此須要有一個參數來控制SGA使用虛擬內存的最大大小,這個參數就是SGA_MAX_SIZE。當實例啓動後,
各個內存區只分配實例所須要的最小大小,在隨後的運行過程當中,再根據須要擴展他們的大小,而他們的總和大小受到了SGA_MAX_SIZE的限制。
對於OLTP系統,參考:
系統內存html |
SGA_MAX_SIZE值java |
1Gweb |
400-500Msql |
2G數據庫 |
1Gwindows |
4G緩存 |
2500M服務器 |
8G架構 |
5G |
2.6 PRE_PAGE_SGA
oracle實例啓動時,會只載入各個內存區最小的大小。而其餘SGA內存只做爲虛擬內存分配,
只有當進程touch到相應的頁時,纔會置換到物理內存中。
但咱們也許但願實例一啓動後,全部SGA
都分配到物理內存。這時就能夠經過設置PRE_PAGE_SGA參數來達到目的了。這個參數的默認值
爲FALSE,
即不將所有SGA置入物理內存中。當設置爲TRUE時,實例啓動會將所有SGA置入物理
內存中。它可使實例啓動達到它的最大性能狀態,可是,
啓動時間也會更長(由於爲了使全部SGA
都置入物理內存中,oracle進程須要touch全部的SGA頁)。
2.7 LOCK_SGA
爲了保證SGA都被鎖定在物理內存中,而沒必要頁入/頁出,能夠經過參數LOCK_SGA來控制。
這個參數默認值爲FALSE,當指定爲TRUE時,
能夠將所有SGA都鎖定在物理內存中。固然,
有些系統不支持內存鎖定,這個參數也就無效了。
2.8 SGA_TARGET
這裏要介紹的時Oracle10g中引入的一個很是重要的參數。在10g以前,SGA的各個內存區
的大小都須要經過各自的參數指定,
而且都沒法超過參數指定大小的值,
儘管他們之和可能並
沒有達到SGA的最大限制。此外,一旦分配後,各個區的內存只能給本區使用,
相互之間是不能共享的。
拿SGA中兩個最重要的
內存區Buffer Cache
和Shared Pool來講,它們兩個對實例的性能影響最大,
可是就有這樣的
矛盾存在:在內存資源有限的狀況下,某些時候數據被cache的需求很是大,
爲了提升buffer hit,
就須要增長Buffer Cache,但因爲SGA有限,
只能從其餘區「搶」過來——如縮小Shared Pool,
增長Buffer Cache;而有時又有大塊的PLSQL代碼被解析駐入內存中,
致使Shared Pool不足,
甚至出現4031錯誤,
又須要擴大Shared Pool,這時可能又須要人爲干預,從Buffer Cache中將內存奪回來。
有了這個新的特性後,SGA中的這種內存矛盾就迎刃而解了。這一特性被稱爲自動共享內存管理
(Automatic Shared Memory Management ASMM)。
而控制這一特性的,
也就僅僅是這一個參數SGA_TARGE。
設置這個參數後,你就不須要爲每一個內存區來指定大小了。SGA_TARGET指定了SGA可使用
的最大內存大小,
而SGA中各個內存的
大小由Oracle自行控制,不須要人爲指定。Oracle能夠隨時調節各個區域的大小,
使之達到系
統性能最佳狀態的個
最合理大小,而且控制他們之和在SGA_TARGET指定的
值以內。
一旦給SGA_TARGET指定值後
(默認爲0,即沒有啓動ASMM),就自動啓動了ASMM特性。
3、oracle 內存調優辦法
當項目的生產環境出現性能問題,咱們如何經過判斷那些參數須要調整呢?
3.1 檢查ORACLE實例的Library Cache命中率:
標準:通常是大於99%
檢查方式:select 1-(sum(reloads)/sum(pins)) "Library cache Hit Ratio" from v$librarycache;
處理措施:
若是Library cache Hit Ratio的值低於99%,應調高shared_pool_size的大小。經過sqlplus鏈接數據庫執行以下命令,調整shared_pool_size的大小:
SQL>alter system flush shared_pool;
SQL>alter system set shared_pool_size=設定值 scope=spfile;
3.2 檢查ORACLE實例的Data Buffer(數據緩衝區)命中率:
標準:通常是大於90%
檢查方式:
select 1 - (phy.value / (cur.value + con.value)) "HIT RATIO"
from v$sysstat cur, v$sysstat con, v$sysstat phy
where cur.name = 'db block gets'
and con.name = 'consistent gets'
and phy.name = 'physical reads';
處理措施:
若是HIT RATIO的值低於90%,應調高db_cache_size的大小。經過sqlplus鏈接數據庫執行以下命令,
調整db_cache_size的大小
SQL>alter system set db_cache_size=設定值 scope=spfile
3.3 檢查ORACLE實例的Dictionary Cache命中率:
select 1 - (sum(getmisses) / sum(gets)) "Data Dictionary Hit Ratio"
若是Data Dictionary Hit Ratio的值低於95%,應調高shared_pool_size的大小。經過sqlplus鏈接數據庫執行以下命令,調整shared_pool_size的大小:
SQL>alter system flush shared_pool;
SQL>alter system set shared_pool_size=設定值 scope=spfile;
3.4 檢查ORACLE實例的Log Buffer命中率:
select (req.value * 5000) / entries.value "Ratio"
from v$sysstat req, v$sysstat entries
where req.name = 'redo log space requests'
and entries.name = 'redo entries';
若是Ratio高於1%,應調高log_buffer的大小。經過sqlplus鏈接數據庫執行以下命令,調整log_buffer的大小:
SQL>alter system set log_buffer=設定值 scope=spfile;
3.5 檢查undo_retention:
標準:undo_retention 的值必須大於max(maxquerylen)的值
col undo_retention format a30
select value "undo_retention" from v$parameter where name='undo_retention';
select max(maxquerylen) From v$undostat Where begin_time>sysdate-(1/4);
若是不知足要求,須要調高undo_retention 的值。經過sqlplus 鏈接數據庫執行以下命
SQL>alter system set undo_retention= 設定值 scope=spfile;
注:
32bit 和 64bit 的問題
對於 oracle 來講,存在着 32bit 與 64bit 的問題。這個問題影響到的主要是 SGA 的大小。在 32bit 的數據庫下,一般 oracle 只能使用不超過 1.7G 的內存,即便咱們擁有 12G 的內存,可是咱們卻只能使用 1.7G,這是一個莫大的遺憾。假如咱們安裝 64bit 的數據庫,咱們就可使用很大的內存,咱們幾乎不可能達到上限。可是 64bit 的數據庫必須安裝在 64bit 的操做系統上,惋惜目前 windows 上只能安裝 32bit 的數據庫,咱們經過下面的方式能夠查看數據庫是 32bit 仍是 64bit
可是在特定的操做系統下,可能提供了必定的手段,使得咱們可使用超過 1.7G 的內存,達到 2G 以上甚至更多。