一、 Oracle數據庫服務器
數據庫在各個行業都會有使用到;其實,我們平時無論是在與客戶溝通或者交流中,所說的Oracle數據庫是指Oracle數據庫服務器(Oracle
Server),它由Oracle實例(Oracle Instance)和Oracle數據庫(Oracle Database)組成。
Oracle實例:就是用于與數據庫進行交互的一片內存區域和后臺進程的集合;實例啟動時,系統首先在服務器內存中分配系統全局區(System
Global
Area),構成Oracle內存結構,然后啟動必須的常駐內存的操作系統進程,組成Oracle的進程結構,內存結構和進程結構即構成Oracle實例。
Oracle數據庫:物理文件的集合,包括數據文件、重做日志文件、控制文件、參數文件、密碼文件、歸檔日志文件、備份文件、告警日志文件、跟蹤文件等等;其中數據文件、控制文件、重做日志文件和參數文件是必須的,其他文件可選。
一個實例只能對應/操作一個數據庫,一個數據庫可以由一個或多個實例操作(比如RAC)。
二、 Oracle實例
Oracle實例就是用于與數據庫進行交互的一片內存區域和后臺進程的集合,一個單獨的數據庫可以被多個實例訪問,Oracle早期的并行服務器OPS演變到現在普遍使用RAC集群架構。
實例啟動時,系統首先在服務器內存中分配系統全局區(System Global
Area),構成Oracle內存結構,然后啟動必須的常駐內存的操作系統進程,組成Oracle的進程結構,內存結構和進程結構即構成Oracle實例。實例在操作系統中用ORACLE_SID來標識,在Oracle中用參數實例名(Instance
Name)來標識, 它們兩個的值是相同的。下面介紹實例的組成和作用:
1、系統全局區(System Global Area)
系統全局區System Global Area(SGA)是系統分配的共享的內存結構,
當數據庫實例啟動時,SGA的內存被自動分配;當數據庫實例關閉時,SGA內存被回收;SGA可以包含一個數據庫實例的數據或控制信息。當多個用戶連接到同一個數據庫實例時,在實例的SGA中,數據可以被多個用戶共享;SGA是占用內存最大的一個區域,同時也是影響數據庫性能的重要因素。SGA主要包括:
1)、共享緩沖區(Shared Pool)
共享池(Shared Pool)就是我們常說的SQL共享池,它還包括庫緩沖區(Library Cache)和數據字典緩沖區(Data
Dictionary Cache);共享緩沖區大小由參數SHARED_POOL_SIZE設定。
a)、庫緩沖區:存儲對數據庫進行操作的語句信息,包括執行計劃及運行數據庫的SQL語句的語法分析樹,所有用戶在第二次運行相同的SQL語句時,可以利用SQL共享池中可用的語法分析信息來加快執行速度;庫緩沖區通過最近最少使用(LRU,LeastRecentlyUsed)算法來管理可用空間,當SQL共享池填滿時,將從庫緩存區中刪掉最近最少使用的執行路徑和語法分析樹,以便為新的條目騰出空間;如果SQL共享池太小,語句將被連續不斷地再裝入到庫緩存區,從而影響操作性能。
b)、數據字典緩沖區(Database Buffer
Cache):數據庫對象的信息存儲在數據字典表中,這些信息包括用戶帳號數據、權限、數據文件名、段名、表結構及表說明等,當數據庫需要這些信息(如用戶對表是否有讀寫權限)時,將讀取數據字典表且將返回的數據存儲在字典緩存區中。數據字典緩沖區使用最近最少使用(LRU,LeastRecentlyUsed)算法來管理,數據字典緩存區的大小由數據庫內部管理,如果字典緩存區太小,數據庫需要反復查詢數據字典表以獲取訪問數據庫所需的信息,這些查詢由循環調用(recuesivecall)事件完成。
2)、數據庫緩沖區(Database Buffer Cache)
數據庫緩沖區由DB_CACHE_SIZE參數設定,Oracle使用最近最少使用(LRU,LeastRecentlyUsed)算法來管理數據庫緩沖區可用空間;當存儲區需要空閑空間時,最近最少使用塊將被移出,新數據塊將在存儲區代替它的位置,通過這種方法,將最頻繁使用的數據保存在存儲區中;如果SGA的大小不足以容納所有最常使用的數據,那么,不同的對象將爭用數據庫緩存區中的空間;當多個應用程序共享同一個SGA時,很有可能發生這種情況。此時,每個應用的最近使用段都將與其他應用的最近使用段爭奪SGA中的空間,這樣,數據庫緩沖區的數據請求將出現較低的命中率,導致系統性能下降。
3)、重做日志緩沖區(Redo Log Buffer Cache)
Redo
log包含所有的數據庫變化歷史,數據庫的所有操作變化,均按照寫入重做日志緩沖區先于數據塊緩沖區、寫入重做日志文件先于寫入數據文件;當發生提交動作時,將重做日志緩沖區變化刷到重做日志文件。在被寫入聯機重做日志文件之前,事務首先被記錄在稱作重做日志緩沖區(Redo
Log
Buffer)的SGA中,數據庫可以周期地分批向聯機重做日志文件中寫重做項的內容,從而優化這個操作。重做日志緩沖區的大小(以字節為單位)由LOG_BUFFER參數決定。
4)、大池(Large Pool)
大池屬于一個可選內存區,如果數據庫使用線程服務器選項或頻繁執行備份、恢復操作,只要創建一個大池,就可以更有效地管理這些操作。大池將致力于支持大型SQL命令,利用大池,就可以防止這些大型SQL命令爭用SQL共享池,從而減少再裝入到庫緩存區中的語句數量。大池的大小(以字節為單位)由LARGE_POOL_SIZE參數設置,可以使用LARGE_POOL_MIN_ALLOC參數設置大池的最小分配,可以使用SHARED_POOL_RESERVED_SIZE參數為SQL大型語句保留一部分SQL共享池。
5)、Java池(Java Pool)
Java池為Java命令提供語法分析,Java池的大小(以字節為單位)由JAVA_POOL_SIZE參數設置,缺省值為10MB。
6)、多緩沖池
可以在SGA中創建多個緩沖池,能夠用多個緩沖池把大數據集與其他的應用程序分開,以減少數據庫緩存區內相同資源爭用;對于創建的每一個緩沖池,都要設定LRU鎖存器的大小和數量,緩沖區的數量必須至少比LRU鎖存器的數量多50倍。創建緩沖池時,需要設定保存區(KeepArea)的大小和再循環區(RecycleArea)的大小,與SQL共享池的保留區一樣,保存區保持條目,而再循環區則被頻繁地再循環使用。使用BUFFER_POOL_KEEP參數規定來保存區的大小。
2、后臺進程(Background Process)
數據庫實例由內存結構和后臺進程,應用與數據庫的所有操作和交互都由數據庫實例中完成,SGA可以理解為交互平臺,后臺進程則可以理解為SGA與數據庫交互的橋梁。PMON、SMON、DBWRn、LGWRn、CKPT進程為必須的后臺進程,ARCHn、LCKn等為可選后臺進程。
1)、PMON (Process Monitor,進程監控進程)
PMON用于在用戶進程出現故障時進行恢復,清除失效的用戶進程,負責清理內存區域和釋放該進程所使用的資源,如果會話不正常終止時,PMON負責Rollback未提交的事務,釋放資源;同時監控Oracle所有后臺進程(Background
Process)。PMON有規律地被呼醒,檢查是否需要,或者其它進程發現需要時可以被調用。PMON進程要重置活動事務表的狀態,釋放鎖,將該故障的進程的ID從活動進程表中移去。PMON還周期地檢查調度進程(DISPATCHER)和服務器進程的狀態,如果已死,則重新啟動(不包括有意刪除的進程)。
2)、SMON(System Monitor Process,系統監控進程)
SMON進程在實例啟動時,如果有需要則執行實例恢復,在實例恢復過程中,如果由于文件讀取錯誤或所需文件處于脫機狀態而導致某些異常終止的事務未被恢復,SMON
將在表空間或文件恢復聯機狀態后再次恢復這些事務。SMON還負責清理不再使用的臨時段(temporary
segment)以及為數據字典管理的表空間(dictionary managed
tablespace)合并相鄰的可用數據擴展(extent)。在具有并行服務器選項的環境下(RAC),SMON對有故障CPU或實例進行實例恢復(Instance
Recovery)。SMON進程有規律地被呼醒,檢查是否需要,或者其它進程發現需要時可以被調用。
3)、DBWn (database writer,數據庫寫入進程)
DBWn進程是負責緩沖存儲區管理的一個Oracle后臺進程,通過使用最近最少使用(LRU,LeastRecentlyUsed)算法來管理,保持內存中的數據塊是最近使用的,使I/O最小,將dirty
buffer寫入到datafile中,維護數據緩沖區的清理,以使用戶進程總能找到足夠的空閑緩沖區。DBWn進程用于將數據緩沖的數據寫入數據文件,是負責數據緩沖區管理的一個Background
Process,默認數量1個,最多10個,由參數為db_writer_processes設置。DBWn進程在以下情況觸發:
a)、沒有空閑緩沖區(no free buffers) b)、達到臟緩沖區閥值(dirty buffer threshold
reached) c)、檢查點(checkpoint) d)、表空間offline(tablespace offline)
e)、超時,每次3秒(time out) f)、drop/truncate表(drop table/truncate table)
4)、LGWR(Log writer,日志寫入進程)
LGWR進程將日志緩沖區寫入磁盤上的一個日志文件,它是負責管理日志緩沖區的一個Oracle后臺進程。LGWR進程同步地寫入到活動的鏡象在線日志文件組。如果組中一個文件被刪除或不可用,LGWR可繼續地寫入該組的其它文件。日志緩沖區是一個循環緩沖區,當LGWR將日志緩沖區的日志項寫入日志文件后,服務器進程可將新的日志項寫入到該日志緩沖區。LGWR
通常寫得很快,可確保日志緩沖區總有空間可寫入新的日志項。
Oracle使用快速提交機制,當用戶發出Commit語句時,一個Commit記錄立即放入日志緩沖區,但相應的數據緩沖區改變是被延遲,直到在更有效時才將它們寫入數據文件。當一事務提交時,被賦給一個系統修改號(SCN),它同事務日志項一起記錄在日志中。由于SCN記錄在日志中,以致在并行服務器選項配置情況下,恢復操作可以同步。有時候當需要更多的日志緩沖區時,LWGR在一個事務提交前就將日志項寫出,而這些日志項僅當在以后事務提交后才永久化。LGWR進程管理日志緩沖區,將數據庫的更改寫入日志文件,以便維護數據的一致性,并為數據丟失后進行恢復提供依據。Oracle通過延遲寫日志來優化disk
I/O讀寫,以下4種情況之一Oracle會觸發LGWR進程寫日志: a)、當用戶進程提交一事務時寫入一個提交記錄。
b)、每三秒將日志緩沖區輸出。 c)、當日志緩沖區的1/3已滿時將日志緩沖區輸出。
d)、當DBWR將修改緩沖區寫入磁盤時則將日志緩沖區輸出。
5)、CKPT (CheckPoint,檢查點進程)
CKPT進程負責通知DBWRn和LGWRn將臟緩沖區寫入磁盤,以及時消除因DBWRn/LGWRn延遲寫所造成的數據不一致情況,確保內存中的數據塊被規律地寫入文件,并對數據庫數據庫控制文件和數據文件進行更新同步(修改文件時間頭部),以記錄下當前的數據庫結構和狀態。檢查點(CheckPoint)的作用是及時保證進行延遲寫,防止數據庫出現不一致情況;及時同步各類數據文件,防止各類數據文件出現不一致情況。LGWR后臺進程是將log
buffer中的數據寫到日志文件的進程,是oracle相當重要的一個后臺進程,LGWR進程觸發的條件為以下4種情況之一:
a)、每3秒鐘;也就是該進程最多休眠3秒鐘,休眠時觸發rdbms ipc message事件;
LGWR將buffer中的數據寫到日志文件時,觸發log file parallel write事件;
b)、在事務提交時(COMMIT),此時會觸發LGWR進程寫完后才返回提交成功,在等待LGWR進程寫的過程中將觸發log file
sync事件; c)、DBWn進程寫入數據文件之前; d)、Redo log
Buffer三分之一滿時,這個數字是有一個隱含參數_log_io_size控制,該值的默認值是log
buffer大小的1/3;該值的最大值為3MB,所以Redo log buffer多于1MB的變化記錄時也會觸發LGWR進程寫;
由于Oracle中LGWR和DBWR工作的不一致,Oracle引入了檢查點的概念,用于同步數據庫,保證數據庫的一致性。在Oracle里面,檢查點分為兩種:完全檢查點和增量檢查點。下面我們分別介紹這兩種檢查點的作用:
a)、完全檢查點
在Oracle8i之前,數據庫的發生的檢查點都是完全檢查點,完全檢查點會將數據緩沖區里面所有的臟數據塊寫入相應的數據文件中,并且同步數據文件頭和控制文件,保證數據庫的一致。完全檢查點在8i之后只有在下列兩種情況下才會發生:
1)、DBA手工執行alter system checkpoint的命令;
2)、數據庫正常shutdown(immediate,transcational,normal)。
由于完全檢查點會將所有的臟數據庫塊寫入,巨大的IO往往會影響到數據庫的性能。因此Oracle從8i開始引入了增量檢查點的概念。 b)、
增量檢查點
Oracle從8i開始引入了檢查點隊列這么一種概念,用于記錄數據庫里面當前所有的臟數據塊的信息,DBWR根據這個隊列而將臟數據塊寫入到數據文件中。檢查點隊列按時間先后記錄著數據庫里面臟數據塊的信息,里面的條目包含RBA(Redo
Block
Address,重做日志里面用于標識檢查點期間數據塊在重做日志里面第一次發生更改的編號)和數據塊的數據文件號和塊號。在檢查點期間不論數據塊更改幾次,它在檢查點隊列里面的位置始終保持不變,檢查點隊列也只會記錄它最早的RBA,從而保證最早更改的數據塊能夠盡快寫入。當DBWR將檢查點隊列里面的臟數據塊寫入到數據文件后,檢查點的位置也要相應地往后移,CKPT每三秒會在控制文件中記錄檢查點的位置,以表示Instance
Recovery時開始恢復的日志條目,這個概念稱為檢查點的“心跳”(heartbeat)。檢查點位置發生變更后,Oracle里面通過4個參數用于控制檢查點位置和最后的重做日志條目之間的距離。在這里面需要指出的是,多數人會將這4個參數看作控制增量檢查點發生的時間。事實上這是錯誤的,這4個參數是用于控制檢查點隊列里面的條目數量,而不是控制檢查點的發生。
6)、ARCH(archiver,歸檔進程)
ARCH進程用于管理歸檔日志文件,當數據庫運行在archivelog模式下時,將循環使用的redo
log文件組在被復寫覆蓋前進行歸檔備份到其他指定存儲設備,為數據丟失后進行數據恢復。當Redo
Log日志切換時觸發ARCH進程進行日志歸檔。
7)、RECO(Recovery,恢復進程)
RECO進程是在具有分布式選項時所使用的一個進程,自動地解決在分布式事務中的故障,維持在分布式環境中的數據的一致性。主要工作,就是recover那些兩階段提交的但由于網絡或其它原因造成狀態為prepared
的掛起事務。一個結點RECO后臺進程自動地連接到包含有懸而未決的分布式事務的其它數據庫中,RECO自動地解決所有的懸而不決的事務。任何相應于已處理的懸而不決的事務的行將從每一個數據庫的懸掛事務表中刪去。當某些節點反饋yes給事務協調器可以提交時,但事務協調器還未正式發出可以提交的最后指示時,由于網絡的原因,這些節點失去了和事務協調節點的聯系,此時這些事務就成為了一個in-doubt
distributed
transaction。此時,RECO就負責定期的聯系事務協調器,當聯系到時,就會提交或者回滾這些事務了。RECO后臺進程僅當在允許分布式事務的系統,而且DISTRIBUTED_TRANSACTIONS參數是大于0時會用到該后臺進程。
8)、LCKn (lock,鎖進程)
LCKn進程是在具有并行服務器選件環境下使用,用于實例間的封鎖,可多至10個進程(LCK0,LCK1……,LCK9)。
9)、Dnnn (dispatcher,調度進程)
Dnnn進程允許用戶進程共享有限的服務器進程(SERVER PROCESS)。沒有調度進程時,每個用戶進程需要一個專用服務進