Oracle體系結構:記憶體結構和程式結構(轉)

zyb200發表於2007-06-06

(一)記憶體結構和程式結構 Oracle資料庫的總體結構如下圖:

[@more@]

Oracle體系結構:記憶體結構和程式結構(轉)screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" style="WIDTH: 424px; HEIGHT: 278px" onclick="if(!this.resized) {return true;} else {window.open('');}" height="278" src="" width="424" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" border="0" /> 1:Oracle例項(Instance)
在一個伺服器中,每一個執行的Oracle資料庫都與一個資料庫例項相聯絡,例項是我們
訪問資料庫的手段。
例項在作業系統中用ORACLE_SID來標識,在Oracle中用引數INSTANCE_NAME來標識,
它們兩個的值是相同的。資料庫啟動時,系統首先在伺服器記憶體中分配系統全域性區(SGA),
構成了Oracle的記憶體結構,然後啟動若干個常駐記憶體的作業系統程式,即組成了Oracle的
程式結構,記憶體區域和後臺程式合稱為一個Oracle例項。

Oracle體系結構:記憶體結構和程式結構(轉)screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('');}" src="" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" border="0" />

資料庫與例項之間是1對1/n的關係,在非並行的資料庫系統中每個Oracle資料庫與一個
例項相對應;在並行的資料庫系統中,一個資料庫會對應多個例項,同一時間使用者只與一個
例項相聯絡,當某一個例項出現故障時,其他例項自動服務,保證資料庫正常執行。在任何
情況下,每個例項都只可以對應一個資料庫。
2:Oracle 10g動態記憶體管理
記憶體是影響資料庫效能的重要因素,Oracle8i使用靜態記憶體管理,Oracle 10g使用動態
記憶體管理。所謂靜態記憶體管理,就是在資料庫系統中,無論是否有使用者連線,也無論併發用
量大小,只要資料庫服務在執行,就會分配固定大小的記憶體;動態記憶體管理允許在資料庫服
務執行時對記憶體的大小進行修改,讀取大資料塊時使用大記憶體,小資料塊時使用小記憶體,讀
取標準記憶體塊時使用標準記憶體設定。
按照系統對記憶體使用方法的不同,Oracle資料庫的記憶體可以分為以下幾個部分:
•系統全域性區:SGA(System Global Area)
•程式全域性區:PGA(Programe Global Area)
•排序池:(Sort Area)
•大池:(Large Pool)
•Java池:(Java Pool)
2-1:系統全域性區SGA(System Global Area)
SGA是一組為系統分配的共享的記憶體結構,可以包含一個資料庫例項的資料或控制信
息。如果多個使用者連線到同一個資料庫例項,在例項的SGA中,資料可以被多個使用者共享。
當資料庫例項啟動時,SGA的記憶體被自動分配;當資料庫例項關閉時,SGA記憶體被回收。
SGA是佔用記憶體最大的一個區域,同時也是影響資料庫效能的重要因素。
SGA的有關資訊可以透過下面的語句查詢,sga_max_size的大小是不可以動態調整的。
=====================================
SQL> show parameter sga
NAME TYPE VALUE
------------------------------------ ----------- --------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 164M
sga_target big integer 0

SQL> alter system set sga_max_size=100m;
alter system set sga_max_size=100m
*
ERROR at line 1:
ORA-02095: specified initialization parameter cannot be modified
======================================

系統全域性區按作用不同可以分為:
•資料緩衝區
•日誌緩衝區
•共享池
2-1-1:資料緩衝區(Database Buffer Cache)
如果每次執行一個操作時,Oracle都必須從磁碟讀取所有資料塊並在改變它之後
又必須把每一塊寫入磁碟,顯然效率會非常低。資料緩衝區存放需要經常訪問的資料,
供所有使用者使用。修改資料時,首先從資料檔案中取出資料,儲存在資料緩衝區中,
修改/插入資料也儲存在緩衝區中,commit或DBWR(下面有詳細介紹)程式的其他條
件引發時,資料被寫入資料檔案。
資料緩衝區的大小是可以動態調整的,但是不能超過sga_max_size的限制。
======================================
SQL> show parameter db_cache_size
NAME TYPE VALUE
------------------------------------ ----------- -----------------
db_cache_size big integer 24M

SQL> alter system set db_cache_size=128m;
alter system set db_cache_size=128m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00384: Insufficient memory to grow cache
SQL> alter system set db_cache_size=20m;
System altered.

SQL> show parameter db_cache_size;
NAME TYPE VALUE
------------------------------------ ----------- -----------------
db_cache_size big integer 20M

#此處我僅增加了1M都不行?
SQL> alter system set db_cache_size=25m;
alter system set db_cache_size=25m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00384: Insufficient memory to grow cache
#修改顯示格式,方便檢視。
SQL> column name format a40 wrap
SQL> column value format a20 wrap

#下面語句可以用來檢視記憶體空間分配情況,注意SGA各區大小總和。
SQL> select name,value from v$parameter where name like '%size' and value <> '0';

#先將java_pool_size調小,然後再修改db_cache_size
SQL> show parameter java_pool_size;
NAME TYPE VALUE
------------------------------------ ----------- -----
java_pool_size big integer 48M
SQL> alter system set java_pool_size=20m;
System altered.
SQL> alter system set java_pool_size=30m;
System altered.
#上面說明SGA中各區大小總和不能超過sga_max_size。
=====================================
資料緩衝區的大小對資料庫的存區速度有直接影響,多使用者時尤為明顯。有些應
用對速度要求很高,一般要求資料緩衝區的命中率在90%以上。
下面給出一種計算資料緩衝區命中率的方法:
•使用資料字典v$sysstat
=====================================
SQL> select name, value from v$sysstat
2 where name in('session logical reads',
3 'physical reads',
4 'physical reads direct',
5 'physical reads direct (lob)')
NAME VALUE
------------------------------- ----------
session logical reads 895243
physical reads 14992
physical reads direct 34
physical reads direct (lob) 0
======================================
命中率=1-(14992-34-0)/895243
可以讓Oracle給出資料緩衝區大小的建議:
======================================
SQL> alter system set db_cache_advice=on;#開啟該功能
System altered.
SQL> alter system set db_cache_advice=off;#關閉該功能
System altered.
======================================
2-1-2:日誌緩衝區(Log Buffer Cache)
日誌緩衝區用來儲存資料庫的修改資訊。該區對資料庫效能的影響很小,有關日
志後面還會有詳細的介紹。
查詢日誌緩衝區大小:
SQL> show parameter log_buffer
NAME TYPE VALUE
---------- ----------- -------
log_buffer integer 262144
2-1-3:共享池(Share Pool)
共享池是對SQL,PL/SQL程式進行語法分析,編譯,執行的記憶體區域。
它包含三個部分:(都不可單獨定義大小,必須透過share pool間接定義)。
•庫緩衝區(Library Cache)包含SQL,PL/SQL語句的分析碼,執行計劃。
•資料字典緩衝區(Data Dictionary Cache)表,列定義,許可權。
•使用者全域性區(Usr Global Area)使用者MTS會話資訊。
共享池的大小可以動態修改:
======================================
SQL> show parameter shared_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------
__shared_pool_size big integer 80M
shared_pool_size big integer 80M

SQL> alter system set shared_pool_size=78m
System altered.
======================================
#上面的__shared_pool_size一行奇怪?
2-2:程式全域性區PGA(Programe Global Area)
程式全域性區是包含單個使用者或伺服器資料和控制資訊的記憶體區域,它是在使用者程式連
接到Oracle並建立一個會話時由Oracle自動分配的,不可共享,主要用於使用者在程式設計存
儲變數和陣列。

Oracle體系結構:記憶體結構和程式結構(轉)screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" style="WIDTH: 445px; HEIGHT: 234px" onclick="if(!this.resized) {return true;} else {window.open('');}" height="234" src="" width="445" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" border="0" />

如上圖:
•Stack Space是用來儲存使用者會話變數和陣列的儲存區域;
•User Session Data是為使用者會話使用的附加儲存區。
|--Session Information
|--Sort Area
|--Cursor Information
注意Session information(使用者會話資訊)在獨佔伺服器中與在共享伺服器中所處
的記憶體區域是不同的。

2-3:排序區,大池,Java池
排序區(Sort Area)為有排序要求的SQL語句提供記憶體空間。系統使用專用的記憶體區
域進行資料排序,這部分空間就是排序區。在Oracle資料庫中,使用者資料的排序可使用
兩個區域,一個是記憶體排序區,一個是磁碟臨時段,系統優先使用記憶體排序區進行排序。
如果記憶體不夠,Orcle自動使用磁碟臨時表空間進行排序。為提高資料排序的速度,建議
儘量使用記憶體排序區,而不要使用臨時段。
引數sort_area_size用來設定排序區大小。(好象不能動態修改?)
大池(Large Pool)用於資料庫備份工具--恢復管理器(RMAN:Recovery Manager)。
Large Pool的大小由large_pool_size確定,可用下面語句查詢和修改:
=========================================
SQL> show parameter large_pool_size
NAME TYPE VALUE
----------------- ----------- -------
large_pool_size big integer 8M
SQL> alter system set large_pool_size=7m;
System altered.
=========================================

Java池主要用於Java語言開發,一般來說不低於20M。其大小由java_pool_size來
確定,可以動態調整。
2-4:Oracle自動共享記憶體管理(Automatic Shared Memory(SGA) Management)
在Oracle 8i/9i中資料庫管理員必須手動調整SGA各區的各個引數取值,每個區要根據
負荷輕重分別設定,如果設定不當,比如當某個區負荷增大時,沒有調整該區記憶體大小,則
可能出現ORA-4031:unable to allocate ...bytes of shared memory錯誤。
在Oracle 10g中,將引數STATISTICS_LEVEL設定為TYPICAL/ALL,使用SGA_TARGET指
定SGA區總大小,資料庫會根據需要在各個元件之間自動分配記憶體大小。
下面是系統自動調整的區域:
•固定SGA區及其他•共享池•資料緩衝區• Java池•大池。
注意:如果不設定SGA_TARGET,則自動共享記憶體管理功能被禁止。
==========================================
SQL> show parameter statistics_level
NAME TYPE VALUE
--------------------- ----------- ------------
statistics_level string TYPICAL

SQL> alter system set statistics_level=all;
System altered.
#typical和all有什麼區別?

SQL> alter system set statistics_level=typical;
System altered.
SQL> show parameter sga_target
NAME TYPE VALUE
------------- ----------- ----------
sga_target big integer 0
SQL> alter system set sga_target=170m;
alter system set sga_target=170m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00823: Specified value of sga_target greater than sga_max_size
SQL> alter system set sga_target=20m;
System altered.
#不過後來又發現sga_target的值變成了140M? 下面是語句執行情況。
SQL> show parameter sga_target
NAME TYPE VALUE
------------- ----------- -------
sga_target big integer 140M

SQL> alter system set sga_target=0;
System altered.
SQL> show parameter sga_target
NAME TYPE VALUE
------------------------------------ ----------- ------
sga_target big integer 0
#改為20M
SQL> alter system set sga_target=20m;
System altered.
#顯示的是140M
SQL> show parameter sga_target
NAME TYPE VALUE
------------------------------------ ----------- ------
sga_target big integer 140M
#不可縮減?
SQL> alter system set sga_target=130m;
alter system set sga_target=130m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00827: could not shrink sga_target to specified value

#不可增加
SQL> alter system set sga_target=141m;
alter system set sga_target=141m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00823: Specified value of sga_target greater than sga_max_size

3:Oracle例項的程式結構(Process Structure)
Oracle包含三類程式:
•使用者程式(User Process)
•伺服器程式(Server Process)
•後臺程式(Background Process)

3-1:使用者程式和伺服器程式
當資料庫使用者請求連線到Oracle的服務時啟動使用者程式(比如啟動SQLPlus時)。
•使用者程式首先必須建立一個連線。
•使用者不能直接與Oracle伺服器,必須透過伺服器程式互動。
•伺服器程式是使用者程式與伺服器互動的橋樑,它可以與Oracle Server直接互動。
•伺服器程式可以有共享和獨佔兩種形式。

Oracle體系結構:記憶體結構和程式結構(轉)screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" style="WIDTH: 430px; HEIGHT: 243px" onclick="if(!this.resized) {return true;} else {window.open('');}" height="243" src="" width="430" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" border="0" />



3-2:後臺程式(Backgroung Process)
資料庫的物理結構與記憶體結構之間的互動要透過後臺程式來完成。資料庫的後臺程式包
含兩類,一類是必須的,一類是可選的:
•Mandatory background processes
|--DBWn(Database Writer):資料寫入
|--PMON(Process Moniter):程式監控
|--LGWR(Log Writer):日誌寫入
|--SMON(System Moniter):系統監控
|--RECO(Recovery):恢復
|--CKPT(Chekpoint):檢查點
•Optional background processes
|--ARCn(Archiver):歸檔
|--LCKn(Lock):鎖
|--Dnnn(Dispatcher):排程
|--......
可以用下面的語句檢視正在執行的後臺程式:
=========================================
SQL> select * from v$bgprocess where paddr<>'00';
PADDR PSERIAL# NAME DESCRIPTION
-------- ---------- ----- -------------------------------
6B0ED064 1 PMON process cleanup
6B0ED4E4 1 MMAN Memory Manager
6B0ED964 1 DBW0 db writer process 0
6B0EDDE4 1 LGWR Redo etc.
6B0EE264 1 CKPT checkpoint
6B0EE6E4 1 SMON System Monitor Process
6B0EEB64 1 RECO distributed recovery
6B0EEFE4 1 CJQ0 Job Queue Coordinator
6B0F01E4 1 QMNC AQ Coordinator
6B0F0664 1 MMON Manageability Monitor Process
6B0F0AE4 1 MMNL Manageability Monitor Process 2
========================================
3-2-1:DBWR(Database Writer,資料寫入程式)
將資料緩衝區的資料寫入資料檔案,是負責資料緩衝區管理的一個後臺程式。
當資料緩衝區中的一資料被修改後,就標記為dirty,DBWR程式將資料緩衝區中“髒”
資料寫入資料檔案,保持資料緩衝區的”乾淨“。由於資料緩衝區的資料被使用者修改並佔
用,空閒資料緩衝區會不斷減少,當使用者程式要從磁碟讀取資料塊到資料緩衝區卻無法找
到足夠的空閒資料緩衝區時,DBWR將資料緩衝區內容寫入磁碟,使使用者程式總可以得到足
夠的空閒資料緩衝區。
DBWR的作用:
•管理資料緩衝區,以便使用者程式總能夠找到足夠的空閒緩衝區。
•將所有修改後的緩衝區資料寫入資料檔案。
•使用LRU(最近最少使用)演算法保持緩衝區資料是最近經常使用的。
•透過延遲寫來最佳化磁碟I/0讀寫。

Oracle體系結構:記憶體結構和程式結構(轉)screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" style="WIDTH: 454px; HEIGHT: 354px" onclick="if(!this.resized) {return true;} else {window.open('');}" height="354" src="" width="454" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" border="0" />
3-2-2:LGWR(Log Writer,日誌寫入程式)
將日誌資料從日誌緩衝區寫入磁碟日誌檔案組。資料庫在執行時,如果對資料庫進行修
改則產生日誌資訊,日誌資訊首先產生於日誌緩衝區。當日志達到一定數量時,由LGWR將
將日誌資料寫入到日誌檔案組,再經過日誌切換,由歸檔程式(ARCH)將日誌資料寫入歸
檔程式(前提是資料庫執行在歸檔模式下)。資料庫遵循寫日誌優先原則,即在寫資料之前
先寫日誌。

Oracle體系結構:記憶體結構和程式結構(轉)screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" style="WIDTH: 369px; HEIGHT: 235px" onclick="if(!this.resized) {return true;} else {window.open('');}" height="235" src="" width="369" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" border="0" />

簡單介紹
•ARCH(Archiver,歸檔程式)
Oracle資料庫有兩種執行模式,歸檔(ARCHIVELOG),非歸檔(NOARCHIVELOG)模式。
以非歸檔模式執行時日誌在切換時被直接覆蓋,不產生歸檔日誌,這是資料庫預設的執行模
式。資料庫執行在歸檔模式時,在日誌切換之前,由ARCH程式將日誌資訊寫入磁碟,也就是
自動備份線上日誌。
Oracle資料庫的Redo檔案數量是有限的,所以Oracle以迴圈的方式向它們中寫入。它順
序寫滿每一個Redo檔案,當達到最後一個時,再迴圈回去開始填寫第一個Redo檔案。如果為
了能恢復資料庫而想儲存日誌檔案,那麼在它們被重新使用之前需要對其進行備份,歸檔進
程管理此工作。
•CKPT(Check Point,檢查點程式)
執行CKPT時,系統對全部資料檔案及控制檔案檔案頭的同步訊號進行修改,以保證資料
庫的同步。檢查點出現在以下情況:
|--在每個日誌切換時產生。
|--上一個檢驗點之後又經過了指定時間。
|--從上一個檢驗點之後,當預定義數量的日誌塊被寫入磁碟之後。
|--資料庫關閉。
|--DBA強制產生。
|--當表空間設定為OFFLINE時。
•SMON(System Moniter,系統監控程式)
SMON在例項啟動時執行例項恢復,並負責清理不再使用的臨時段。
•PMON(Process Monitor,程式監控)
PMON在使用者程式出現故障時進行恢復,負責清理記憶體區域和釋放該程式所使用的資源。
•RECO(Recovery,恢復程式)
RECO用於分散式資料庫維持在分散式環境中的資料的一致性。
•LCKn(Lock,鎖程式)
在並行伺服器中用於多個例項間的封鎖。
•Dnnn(Dispatcher,排程程式)
Dnnn存在於多執行緒伺服器體系結構中,負責將使用者程式連線到伺服器程式,再把結果返
回給使用者程式。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/64429/viewspace-917645/,如需轉載,請註明出處,否則將追究法律責任。

相關文章