oracle体系结构剖析
生活随笔
收集整理的這篇文章主要介紹了
oracle体系结构剖析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、ORACLE事例?
1、ORACLE?實例?
System?Global?Area(SGA)?和?Background?Process?被成為數據庫的實例。?
2、ORACLE?數據庫?
一系列物理文件的集合(數據文件,控制文件,聯機日志,參數文件等)?
3、系統全局共享區(qū)System?Global?Area(SGA)??
System?Global?Area?是一塊巨大的共享內存區(qū)域,他被看做是Oracle?數據庫的一個大緩沖池,這里的數據可以被ORACLE的各個進程共用。其大小可以通過如下語句查看:?
SQL>?select?*?from?v$sga;?
NAME?VALUE?
--------------------?---------?
Fixed?Size?39816?
Variable?Size?259812784?
Database?Buffers?1.049E+09?
Redo?Buffers?327680?
更詳細的信息可以參考V$sgastat、V$buffer_pool?
主要包括以下幾個部分:?
a、?共享池(Shared?pool)?
共享池是SGA中最關鍵的內存片段,特別是在性能和可伸縮性上。一個太小的共享池會扼殺性能,使系統停止,太大的共享池也會有同樣的效果,將會消耗大量的CPU來管理這個共享池。不正確的使用共享池只會帶來災難。共享池主要又可以分為以下兩個部分:?
·SQL語句緩沖(Library?Cache)?
當一個用戶提交一個SQL語句,Oracle會將這句SQL進行分析(parse),這個過程類似于編譯,會耗費相對較多的時間。在分析完這個SQL,Oracle會把他的分析結果給保存在Shared?pool的Library?Cache中,當數據庫第二次執(zhí)行該SQL時,Oracle自動跳過這個分析過程,從而減少了系統運行的時間。這也是為什么第一次運行的SQL?比第二次運行的SQL要慢一點的原因。?
下面舉例說明parse的時間?
SQL>?select?count(*)?fromscpass?;?
COUNT(*)?
----------?
243?
Elapsed:?00:00:00.08?
這是在Share_pool?和Data?buffer?都沒有數據緩?
沖區(qū)的情況下所用的時間?
SQL>?alter?system?flush?SHARED_POOL;?
System?altered.?
清空Share_pool,保留Data?buffer?
SQL>?select?count(*)?from?scpass?;?
COUNT(*)?
----------?
243?
Elapsed:?00:00:00.02?
SQL>?select?count(*)?from?scpass?;?
COUNT(*)?
----------?
243?
Elapsed:?00:00:00.00?
從兩句SQL?的時間差上可以看出該SQL?的Parse?時間約為00:00:00.02?
對于保存在共享池中的SQL語句,可以從V$Sqltext、v$Sqlarea中查詢到,對于編程者來說,要盡量提高語句的重用率,減少語句的分析時間。一個設計的差的應用程序可以毀掉整個數據庫的Share?pool,提高SQL語句的重用率必須先養(yǎng)成良好的變成習慣,盡量使用Bind變量。?
·數據字典緩沖區(qū)(Data?Dictionary?Cache)?
顯而易見,數據字典緩沖區(qū)是ORACLE特地為數據字典準備的一塊緩沖池,供ORACLE內部使用,沒有什么可以說的。?
b、塊緩沖區(qū)高速緩存(Database?Buffer?Cache)?
這些緩沖是對應所有數據文件中的一些被使用到的數據塊。讓他們能夠在內存中進行?操作。在這個級別里沒有系統文件,,戶數據文件,臨時數據文件,回滾段文件之分。也就是任何文件的數據塊都有可能被緩沖。數據庫的任何修改都在該緩沖里完成,并由DBWR進程將修改后的數據寫入磁盤。?
這個緩沖區(qū)的塊基本上在兩個不同的列表中管理。一個是塊的“臟”表(Dirty?List),需要用數據庫塊的書寫器(DBWR)來寫入,另外一個是不臟的塊的列表(Free?List),一般的情況下,是使用最近最少使用(Least?Recently?Used,LRU)算法來管理。?
塊緩沖區(qū)高速緩存又可以細分為以下三個部分(Default?pool,Keep?pool,Recycle?pool)。如果不是人為設置初始化參數(Init.ora),ORACLE將默認為Default?pool。?
由于?操作系統尋址能力的限制,不通過特殊設置,在32位的系統上,塊緩沖區(qū)高速緩存最大可以達到1.7G,在64位系統上,塊緩沖區(qū)高速緩存最大可以達到10G。?
c、重做日志緩沖區(qū)(Redo?log?buffer)?
重做日志文件的緩沖區(qū),對數據庫的任何修改都按順序被記錄在該緩沖,然后由LGWR進程將它寫入磁盤。這些修改信息可能是DML語句,如(Insert,Update,Delete),或DDL語句,如(Create,Alter,Drop等)。?
重做日志緩沖區(qū)的存在是因為內存到內存的?操作比較內存到硬盤的速度快很多,所以重作日志緩沖區(qū)可以加快數據庫的?操作速度,但是考慮的數據庫的一致性與可恢復性,數據在重做日志緩沖區(qū)中的滯留時間不會很長。所以重作日志緩沖區(qū)一般都很小,大于3M之后的重作日志緩沖區(qū)已經沒有太大的實際意義。?
d、Java程序緩沖區(qū)(Java?Pool)?
Java?的程序區(qū),Oracle?8I?以后,Oracle?在內核中加入了對Java的支持。該程序緩沖區(qū)就是為Java?程序保留的。如果不用Java程序沒有必要改變該緩沖區(qū)的默認大小。?
e、大池(Large?Pool)?
大池的得名不是因為大,而是因為它用來分配大塊的內存,處理比共享池更大的內存,在8.0開始引入。?
下面對象使用大池:?
·MTS——在SGA的Large?Pool中分配UGA?
·語句的并行查詢(Parallel?Executeion?of?Statements)——允許進程間消息緩沖區(qū)的分配,用來協調并行查詢服務器?
·備份(Backup)——用于RMAN磁盤I/O緩存?
4、后臺進程(Background?process)?
后臺進程是Oracle的程序,用來管理數據庫的讀寫,恢復和監(jiān)視等工作。Server?Process主要是通過他和user?process進行聯系和溝通,并由他和user?process進行數據的交換。在Unix機器上,Oracle后臺進程相對于操作系統進程,也就是說,一個Oracle后臺進程將啟動一個操作系統進程;在Windows機器上,Oracle后臺進程相對于操作系統線程,打開任務管理器,我們只能看到一個ORACLE.EXE的進程,但是通過另外的工具,就可以看到包含在這里進程中的線程。?
在Unix上可以通過如下方法查看后臺進程:?
ps?–ef?|?grep?ora_?
#?ps?-ef?|?grep?ora_?|?grep?XCLUAT?
oracle?29431?1?0?Sep?02???2:02?ora_dbwr_SID?
oracle?29444?1?0?Sep?02???0:03?ora_ckpt_SID?
oracle?29448?1?0?Sep?02???2:42?ora_smon_SID?
oracle?29442?1?0?Sep?02???3:25?ora_lgwr_SID?
oracle?29427?1?0?Sep?02???0:01?ora_pmon_SID?
a、Oracle系統有5?個基本進程他們是?
DBWR(數據文件寫入進程)?
LGWR(日志文件寫入進程)?
SMON(系統監(jiān)護進程)?
PMON(用戶進程監(jiān)護進程)?
CKPT(檢查點進程,同步數據文件,?日志文件,控制文件)?
b、DBWR?
將修改過的數據緩沖區(qū)的數據寫入對應數據文件?
維護系統內的空緩沖區(qū)?
這里指出幾個容易錯誤的概念:?
·當一個更新提交后,DBWR把數據寫到磁盤并返回給用戶提交完成.?
·DBWR會觸發(fā)CKPT?后臺進程?
·DBWR不會觸發(fā)LGWR?進程?
上面的概念都是錯誤的.?
DBWR是一個很底層的工作進程,他批量的把緩沖區(qū)的數據寫入磁盤。和任何前臺用戶的進程幾乎沒有什么關系,也不受他們的控制。至于DBWR會不會觸發(fā)LGWR和CKPT進程,我們將在下面幾節(jié)里討論。?
DBWR工作的主要條件如下?
·DBWR?超時?
·系統中沒有多的空緩沖區(qū)用來存放數據?
·CKPT?進程觸發(fā)DBWR?等?
c、LGWR?
將重做日志緩沖區(qū)的數據寫入重做日志文件,LGWR是一個必須和前臺用戶進程通信的進程。當數據被修改的時候,系統會產生一個重做日志并記錄在重做日志緩沖區(qū)內。這個重做日志可以類似的認為是以下的一個結構:?
SCN=000000001000?
數據塊ID?
對象ID=0801?
數據行=02?
修改后的數據=0011?
提交的時候,LGWR必須將被修改的數據的重做日志緩沖區(qū)內數據寫入日志數據文件,然后再通知前臺進程提交成功,并由前臺進程通知用戶。從這點可以看出LGWR承擔了維護系統數據完整性的任務。?
LGWR?工作的主要條件如下?
·用戶提交?
·有1/3?重做日志緩沖區(qū)未被寫入磁盤?
·有大于1M?重做日志緩沖區(qū)未被寫入磁盤?
·超時?
·DBWR需要寫入的數據的SCN號大于LGWR?記錄的SCN號,DBWR?觸發(fā)LGWR寫入?
d、SMON?
工作主要包含?
????·清除臨時空間?
????·在系統啟動時,完成系統實例恢復?
????·聚結空閑空間?
????·從不可用的文件中恢復事務的活動?
????·OPS中失敗節(jié)點的實例恢復?
????·清除OBJ$表?
????·縮減回滾段?
????·使回滾段脫機?
e、PMON?
主要用于清除失效的用戶進程,釋放用戶進程所用的資源。如PMON將回滾未提交的工作,釋放鎖,釋放分配給失敗進程的SGA資源。?
f、CKPT?
同步數據文件,日志文件和控制文件,由于DBWR/LGWR的工作原理,造成了數據文件,日志文件,控制文件的不一至,這就需要CKPT進程來同步。CKPT會更新數據文件/控制文件的頭信息。?
CKPT工作的主要條件如下?
·在日志切換的時候?
·數據庫用immediate?,transaction?,?normal?選項shutdown?數據庫的時候?
·根據初始話文件LOG_CHECKPOINT_INTERVAL、LOG_CHECKPOINT_TIMEOUT、FAST_START_IO_TARGET?的設置的數值來確定?
·用戶觸發(fā)?
以下進程的啟動需要手工配置?
g、ARCH?
當數據庫以歸檔方式運行的時候,Oracle會啟動ARCH進程,當重做日志文件被寫滿時,日志文件進行切換,舊的重做日志文件就被ARCH進程復制到一個/多個特定的目錄/遠程機器。這些被復制的重做日志文件被叫做歸檔日志文件。?
h、RECO?
負責解決分布事物中的故障。Oracle可以連接遠程的多個數據庫,當由于網絡問題,有些事物處于懸而未決的狀態(tài)。RECO進程試圖建立與遠程服務器的通信,當故障消除后,RECO進程自動解決所有懸而未決的會話。?
i、服務進程Server?Process?
服務進程的分類?
·專用服務進程(Dedicated?Server?Process)?
一個服務進程對應一個用戶進程?
·共享服務進程(MultiTreaded?Server?Process)?
一個服務進程對應多個用戶進程,輪流為用戶進程服務。?
PGA?&?UGA?
PGA?=?Process?Global?Area?
UGA?=?User?Global?Area?
他保存了用戶的變量、權限、堆棧、排序空間等用戶信息,對于專用服務器進程,UGA在PGA中分配。對于多線程進程,UGA在Large?pool中分配。?
j、用戶進程User?Process?
在客戶端,將用戶的SQL?語句傳遞給服務進程?
5、一個貫穿數據庫全局的概念----系統改變號SCN(System?Change?Number)?
系統改變號,一個由系統內部維護的序列號。當系統需要更新的時候自動增加,他是系統中維持數據的一致性和順序恢復的重要標志。?
a.?查詢語句不會使SCN增加,就算是同時發(fā)生的更新,數據庫內部對應的SCN也是不同的。這樣一來就保證了數據恢復時候的順序。?
b.?維持數據的一致性,當一個查詢執(zhí)行的時候,他會先從系統中得到一個當前的SCN號,在他查找數據的同時,他會檢查每個數據行和他對應的SCN號,只有那些不比他的SCN號大的行才能從對應用戶數據文件的緩沖區(qū)內取出,而那些大于他SCN號的行,就應該從回滾段數據文件的緩沖中取出。?
實例分析:?
一個查詢返回以下5?行?
ID?Name?
------------------------?
1?ShangHai?
2?Beijing?
3?Gugangzhou?
4?ShenZhen?
5?HanZhou?
用戶A從12:00開始運行,到12:05結束在12:01用戶B執(zhí)行了一條Update語句,更新了ID是2的那條記錄把Beijing該成了Tianjing.并提交,這時候用戶A?的那個查詢是不會出現Tianjing的記錄。12:00查詢時候的SCN是N然后用戶B的更新使得系統的SCN變成N+1當用戶A查詢到ID=2的記錄的時候發(fā)現他的SCN已經大于查詢開始時候的SCN,他就會在回滾段數據緩沖中找到SCN=N的那條記錄,并把它返回。?
??
二、ORACLE?數據庫?
ORACLE數據庫的組成——物理操作系統文件的集合。主要包括以下幾種。?
1、控制文件(參數文件init.ora記錄了控制文件的位置)?
控制文件包括如下主要信息?
·數據庫的名字,檢查點信息,數據庫創(chuàng)建的時間戳?
·所有的數據文件,聯機日志文件,歸檔日志文件信息?
·備份信息等?
有了這些信息,Oracle就知道那些文件是數據文件,現在的重做日志文件是哪些,這些都是系統啟動和運行的基本條件,所以他是Oracle運行的根本。如果沒有控制文件系統是不可能啟動的。控制文件是非常重要的,一般采用多個鏡相復制來保護控制文件,或采用RAID來保護控制文件。控制文件的丟失,將使數據庫的恢復變的很復雜。?
控制文件信息可以從V$Controlfile中查詢獲得?
??
2、數據文件(數據文件的詳細信息記載在控制文件中)?
可以通過如下方式查看數據文件?
SQL>?select?name?from?v$datafile;?
NAME?
---------------------------------------------?
/u05/dbf/PROD/system_01.dbf?
/u06/dbf/PROD/temp_01.dbf?
/u04/dbf/PROD/users_01.dbf?
/u09/dbf/PROD/rbs_01.dbf?
/u06/dbf/PROD/applsys_indx_01.dbf?
/u05/dbf/PROD/applsys_data_01.dbf?
從以上可以看出,數據文件大致可以分為以下幾類:?
i.?系統數據文件(system_01.dbf)?
存放系統表和數據字典,一般不放用戶的數據,但是用戶腳本,如過程,函數,包等卻是保存在數據字典中的。?
名詞解釋:數據字典?
數據字典是一些系統表或視圖,他存放系統的信息,他包括數據庫版本,數據文件信息,表與索引等段信息,系統的運行狀態(tài)等各種和系統有關的信息和用戶腳本信息。數據庫管理員可以通過對數據字典的查詢,就可以了解到Oracle的運行狀態(tài)。?
ii.?回滾段文件(rbs_01.dbf)?
如果數據庫進行對數據的修改,那么就必須使用回滾段,回滾段是用來臨時存放修改前的數據(Before?Image)。回滾段通常都放在一個單獨的表空間上(回滾表空間),避免表空間碎片化,這個表空間包含的數據文件就是回滾數據文件。?
iii.?臨時數據文件(temp_01.dbf)?
主要存放用戶的排序等臨時數據,與回滾段相似,臨時段也容易引起表空間碎片化,而且沒有辦法在一個永久表空間上開辟臨時段,所以就必須有一個臨時表空間,它所包含的數據文件就是臨時數據文件,主要用于不能在內存上進行的排序操作。我們必須為用戶指定一個臨時表空間。?
iv.?用戶數據文件(/applsys_data_01.dbf?,applsys_indx_01.dbf)?
存放用戶數據,這里列舉了兩類常見的用戶型數據,一般數據和索引數據,一般來說,如果條件許可的話,可以考慮放在不同的磁盤上。?
3、重做日志文件(聯機重做日志)?
用戶對數據庫進行的任何操作都會記錄在重做日志文件。在了解重做日志之前必須了解重做日志的兩個概念,重做日志組和重做日志組成員(Member),一個數據庫中至少要有兩個日志組文件,一組寫完后再寫另一組,即輪流寫。每個日志組中至少有一個日志成員,一個日志組中的多個日志成員是鏡相關系,有利于日志文件的保護,因為日志文件的損壞,特別是當前聯機日志的損壞,對數據庫的影響是巨大的。?
聯機日志組的交換過程叫做切換,需要特別注意的是,日志切換在一個優(yōu)化效果不好的數據庫中會引起臨時的“掛起”。掛起大致有兩種情況:?
·在歸檔情況下,需要歸檔的日志來不及歸檔,而聯機日志又需要被重新利用?
·檢查點事件還沒有完成(日志切換引起檢查點),而聯機日志需要被重新利用?
解決這種問題的常用手段是:?
i.增加日志組?
ii.增大日志文件成員大小?
通過v$log可以查看日志組,v$logfile可以查看具體的成員文件。?
4、歸檔日志文件?
Oracle可以運行在兩種模式之中,歸檔模式和不歸檔模式。如果不用歸檔模式,當然,你就不會有歸檔日志,但是,你的系統將不會是一個實用系統,特別是不能用于生產系統,因為你可能會丟失數據。但是在歸檔模式中,為了保存用戶的所有修改,在重做日志文件切換后和被覆蓋之間系統將他們另外保存成一組連續(xù)的文件系列,該文件系列就是歸檔日志文件。?
有人或許會說,歸檔日志文件占領我大量的硬盤空間,其實,具體想一想,你是愿意浪費一點磁盤空間來保護你的數據,還是愿意丟失你的數據呢?顯而義見,我們需要保證我們的數據的安全性。其實,歸檔并不是一直占領你的磁盤空間,你可以把她備份到磁帶上,或則刪除上一次完整備份前的所有日志文件。?
5、初始化參數文件?
initSID.ora或init.ora文件,因為版本的不一樣,其位置也可能會不一樣。在8i中,通常位于$ORACLE_HOME/admin/<SID>/Pfile下?
初始化文件記載了許多數據庫的啟動參數,如內存,控制文件,進程數等,在數據庫啟動的時候加載(Nomount時加載),初始化文件記錄了很多重要參數,對數據庫的性能影響很大,如果不是很了解,不要輕易亂改寫,否則會引起數據庫性能下降。?
6、其他文件?
i?.?密碼文件?
用于Oracle?的具有sysdba權限用戶的認證.?
ii.?日志文件?
·報警日志文件(alert.log或alrt<SID>.ora)?
記錄數據庫啟動,關閉和一些重要的出錯信息。數據庫管理員應該經常檢查這個文件,并對出現的問題作出即使的反應。你可以通過以下SQL?找到他的路徑select?value?from?v$PARAMETER?where?name?='background_dump_dest';?
·后臺或用戶跟蹤文件?
系統進程或用戶進程出錯前寫入的信息,一般不可能讀懂,可以通過ORACLE的TKPROF工具轉化為可以讀懂的格式。對于系統進程產生的跟蹤文件與報警日志文件的路徑一樣,用戶跟蹤文件的路徑,你可以通過以下SQL找到他的路徑select?value?from?v$PARAMETER?where?name?='user_dump_dest';?
??
三、ORACLE邏輯結構?
1、?表空間(tablespace)?
表空間是數據庫中的基本邏輯結構,一系列數據文件的集合。一個表空間可以包含多個數據文件,但是一個數據文件只能屬于一個表空間。?
2、?段(Segment)?
段是對象在數據庫中占用的空間,雖然段和數據庫對象是一一對應的,但段是從數據庫存儲的角度來看的。一個段只能屬于一個表空間,當然一個表空間可以有多個段。?
表空間和數據文件是物理存儲上的一對多的關系,表空間和段是邏輯存儲上的一對多的關系,段不直接和數據文件發(fā)生關系。一個段可以屬于多個數據文件,關于段可以指定擴展到哪個數據文件上面。?
段基本可以分為以下四種?
·數據段(Data?Segment)?
·索引段(Index?Segment)?
·回滾段(Rollback?Segment)?
·臨時段(Temporary?Segment)?
3、區(qū)間(Extent)?
關于Extent的翻譯有多種解釋,有的譯作擴展,有的譯作盤區(qū),我這里通常譯為區(qū)間。在一個段中可以存在多個區(qū)間,區(qū)間是為數據一次性預留的一個較大的存儲空間,直到那個區(qū)間被用滿,數據庫會繼續(xù)申請一個新的預留存儲空間,即新的區(qū)間,一直到段的最大區(qū)間數(Max?Extent)或沒有可用的磁盤空間可以申請。?
在ORACLE8i以上版本,理論上一個段可以無窮個區(qū)間,但是多個區(qū)間對ORACLE卻是有性能影響的,ORACLE建議把數據分布在盡量少的區(qū)間上,以減少ORACLE的管理與磁頭的移動。?
4、Oracle數據塊(Block)?
ORACLE最基本的存儲單位,他是OS數據塊的整數倍。ORACLE的操作都是以塊為基本單位,一個區(qū)間可以包含多個塊(如果區(qū)間大小不是塊大小的整數倍,ORACLE實際也擴展到塊的整數倍)。?
5、基本表空間介紹?
a.?系統表空間?
主要存放數據字典和內部系統表基表?
查看數據數據字典的SQL?
select?*?from?dict?
查看內部系統表的SQL?
select?*?from?v$fixed_view_definition?
DBA對系統的系統表中的數據字典必須有一個很深刻的了解,他們必須準備一些基礎的SQL語句,通過這些SQL可以立即了解系統的狀況和數據庫的狀態(tài),這些基本的SQL包括?
系統的剩余空間?
系統的SGA??
狀態(tài)系統的等待?
用戶的權限?
當前的用戶鎖?
緩沖區(qū)的使用狀況等?
在成為DBA?的道路上我們不建議你過分的依賴于OEM/Quest?等優(yōu)秀的數據庫管理工具,因為他們不利于你對數據數據字典的理解,SQL語句可以完成幾乎全部的數據庫管理工作。?
大量的讀少量的寫是該表空間的一個顯著的特點。?
b.?臨時表空間.?
臨時表空間顧名思義是用來存放臨時數據的,例如排序操作的臨時空間,他的空間會在下次系統啟動的時候全部被釋放。?
c.?回滾段表空間?
i.?回滾段在系統中的作用?
當數據庫進行更新插入刪除等操作的時候,新的數據被更新到原來的數據文件,而舊的數據(Before?Image)就被放到回滾段中,如果數據需要回滾,那么可以從回滾段將數據再復制到數據文件中。來完成數據的回滾。在系統恢復的時候,?回滾段可以用來回滾沒有被commit?的數據,解決系統的一直性讀。?
???????回滾段在什么情況下都是大量的寫,一般是少量讀,因此建議把回滾段單獨出來放在一個單獨的設備(如單獨的磁盤或RAID),以減少磁盤的IO爭用。??
ii.?回滾段的工作方式?
·一個回滾表空間可以被劃分成多個回滾段.?
·一個回滾段可以保存多個會話的數據.?
·回滾段是一個圓形的數據模型?
假設回滾段由4?個區(qū)間組成,他們的使用順序就是區(qū)間1à區(qū)間2à區(qū)間3à區(qū)間4à區(qū)間1。也就是說,區(qū)間是可以循環(huán)使用的,當區(qū)間4到區(qū)間1的時候,區(qū)間1里面的會話還沒有結束,?區(qū)間4用完后就不能再用區(qū)間1,這時系統必須分配區(qū)間5,來繼續(xù)為其他會話服務服務。?
我們分析一個Update?語句的完成?
①.?用戶提交一個Update?語句?
②.?Server?Process?檢查內存緩沖.?
如果沒有該數據塊的緩沖,則從磁盤讀入?
i.?如果沒有內存的有效空間,DBWR被啟動將未寫入磁盤的臟緩沖寫入磁盤?
ii.?如果有有效空間,則讀入?
③.?在緩沖內更新數據?
i.?申請一個回滾段入口,將舊數據寫如回滾段?
ii.?加鎖并更新數據?
iii.?并在同時將修改記錄在Redo?log?buffer中?
④.?用戶提交一個Commit?語句?
i.?SCN增加?
ii.?將Redo?log?buffer?寫入Redo?log?file?
iii.?返回用戶Commit?完成?
??
四、ORACLE核心初探?
1、LRU?算法和數據緩沖區(qū)?
我們知道Oracle?數據庫的文件大小遠遠大于Oracle?的所擁有的內存區(qū)域SGA,LRU就是一種盡可能將常用的數據保留在內存的算法。當數據庫需要一個數據緩沖區(qū),他會從數據庫緩沖區(qū)的LRU隊列的尾部找一個空閑的緩沖,將一個數據塊讀入,然后數據庫會把這個緩沖區(qū)放到LRU?隊列的中部,如果該緩沖被其他程序用到的話,那么他會往隊列的頭上移動,如果這個緩沖沒有被其他程序用到,并且沒有被修改過,那么他會慢慢的移動到LRU?隊列的尾部,最終被認為是空緩沖區(qū)被其他數據塊所覆蓋。一旦這個緩沖區(qū)被修改過DBWR把他從LRU隊列中移出,放到LRUW?隊列(也叫贓緩沖區(qū))中,等待DBWR把他們批量寫入數據文件,然后再把他們的緩沖區(qū)連接到LRU隊列的尾部,周而復始的工作。?
理解HASH算法,為了提高速度Oracle在設計中采用了大量的HASH算法,這里我們講一下HASH算法的理論知識,在以后的閱讀中會對Oracle有更好的理解。HASH是一種以空間換取時間的做法。假如我有100萬條數據,以隊列的方式存儲,如果我要從里面找一條數據,那么我要從頭開始找,我所需要的空間是100萬個存儲單元,如果我用HASH的方法來存儲,我把存儲空間劃分為1000*2000的數組,把100萬個數據分別按照如下規(guī)則添入該數組:?
1.?定義一個函數,使得每條數據對應一個0-999的值?
2.?把該行記錄存儲在以函數返回值為下標的數組里?
3.?我們稱該函數為hash?函數f(row).?hash?函數的返回值為hash?值.數組為?
hash?數組HashArray[n][m].?
即有下列公式?
find?a?unused?buffer?in?HashArray[f(row)][?]?
HashArray[f(row)][?]?=?row;?
這樣,當我們需要一個行時候我們只需簡單的計算該行的hash值,然后到下標為hash值的hash數組里找就可以了。即使用最簡單的方法也可以很快的找到?
For?(I=1;I<=2000;?I?++)?
If?(HashArray[f(row)][I]?==?row?)?return;?
Next?
當然HASH算法還是很復雜的,這里只是一個最最簡單的例子。如果大家有興趣可以看看有關數據結構的資料,這里就不具體展開了。?
??
2、LATCH(Oracle內部鎖)?
有許多人問我Latch和Lock?的區(qū)別,其實很簡單,Latch是Oracle內部的Lock,他負責更為細小的內部讀寫,比如Oracle要把用戶更新的數據寫入緩沖區(qū),這時候Oracle就會在該緩沖區(qū)上加上latch,用來防止DBWR把他寫出到磁盤,因為如果沒有這個Latch,DBWR會把一半新一半老沒有用的數據寫到磁盤上。?
??
五、常見問題?
1、實例和SID的關系是什么??
經常有人問SID?是什么?在Oracle?系統中SID?是一個經常出現的變量,如環(huán)境變量ORACLE_SID,?初始化文件initSID.ora,那究竟什么是SID?呢?其實SID?就是Oracle?實例的標識,不同的SID?對應不同的內存緩沖(SGA)和不同的后臺進程。這樣一來我們就可以得當在一臺物理的服務器上可以有多個SID?的數據庫實例。?
2、Oracle數據庫和實例的關系是什么??
數據庫是由物理文件和存取數據文件的實例組成,當存取數據文件的實例是一個的時候,數據庫被稱做單節(jié)點數據庫。這是我們看到的最多的數據庫形式。當然還有一種多節(jié)點數據庫,就是一個以上的實例共同訪問一個數據庫(或者說共同訪問一組數據文件),?更好的提供穩(wěn)定性和并行處理能力。這在8i中被稱為OPS(Oracle?Parallel?Server?),在Oracle9i?中被稱為RAC(real?application?cluster)。在這種數據庫中。兩個/多個實例分別在不同服務器上,所有Oracle?數據文件在共享的磁盤陣列上,多個服務器上的實例可以同時工作,他們通過一個內部的網絡進行通信。如果一臺服務器不能提供服務的話,另一臺會接管它的工作,特別是在關鍵的業(yè)務有很大的潛力。?
3、在運行的數據庫中數據文件中是不是可能存在沒有被提交的數據??
這是可能存在的,因為用戶數據文件的數據是由DBWR寫入的,DBWR是一個很底層的后臺進程,不負責與用戶交互。用戶的交互是由LGWR完成的。?
4、在問題3中,如果存在沒有寫入的數據,那么機器突然斷電,數據完整性會不會損壞??
不會的,因為數據庫的完整性是LGWR來保證的,而且ORACLE保證了DBWR寫入數據文件的任何修改已經被記錄在重做日志文件中。當系統再次啟動的時候,通過讀取重做日志文件就可以知道那些數據沒有被提交。這時候ORACLE?會自動回滾那些數據。所以說聯機日志的損壞,特別是當前聯機日志的損壞,對數據庫的影響是巨大的,可能會導致數據庫的不完整。?
5、數據文件損壞會丟失數據嗎??
可以這么說,如果你有備份和歸檔,就不會。因為所有對數據修改的記錄都在重做日志中有記錄,所以不會丟失數據,你只要恢復以前的備份再用歸檔日志文件恢復和當前的在線重做日志就可以恢復所有數據。?
6、在線重做日志損壞會丟失數據嗎??
以上說了,在線日志對數據庫的損壞是極大的,所以不僅可能丟失數據,還可能引起數據庫的不同步。在重做日志中的所有commit的記錄都會丟失,這也是Oracle?為什么要對在線重做日志文件做鏡像的原因。任何的數據丟失都是不允許的。?
7、我在事務能不能指定不寫回滾段??
不可以的,寫回滾段是ORACLE保證一致性讀和事務一致性的根本。回滾段是高寫入段,建議把它放到單獨的設備上來。?
對于DDL語句,如DROP,TRUNCATE卻可以不寫回滾段(沒有UNDO信息),所以對于整個表的刪除,如果數據量比較大,建議用Truncate?Table的方法。?
不寫聯機日志也是不可能的,但可以在某些特定操作中,可以寫很少的聯機日志,如以NOLOGGING的方式通過Create?table?tablename?as?select創(chuàng)建表,或以Append的方式Insert數據到表,或直接載入等操作。?
六、小結?
這里,我們了解了實例和數據庫的關系,一個數據庫可以有多個實例,但是一個實例卻不可能對應多個數據庫,在一般的情況下,我們都是用的單節(jié)點數據庫,即一個實例僅僅對應一個數據庫。?
我們了解了ORACLE實例的組成,包括內存和后臺進程,進一步解釋了SGA的組成與SGA的作用,并分析了語句重用的好處。在后臺進程中,重要的闡述了DBWR與LGWR,其中DBWR是一個底層的由ORACLE控制的后臺進程,而LGWR負責與用戶交互.?
在ORACLE數據庫中,我們重要闡述了數據庫的物理與邏輯結構,在物理結構中,需要注意四類以下文件:控制文件,聯機日志,數據文件與參數文件。在邏輯結構中,需要清楚每個邏輯結構的關系,從大到小的順序為:表空間à段à區(qū)間à塊。?
最后,簡單的描敘了兩個ORACLE的核心內容,LRU算法與LATCH,并初步闡述了HASH算法的相關內容。有關ORACLE更多的核心內容,可以參考相關資料。
1、ORACLE?實例?
System?Global?Area(SGA)?和?Background?Process?被成為數據庫的實例。?
2、ORACLE?數據庫?
一系列物理文件的集合(數據文件,控制文件,聯機日志,參數文件等)?
3、系統全局共享區(qū)System?Global?Area(SGA)??
System?Global?Area?是一塊巨大的共享內存區(qū)域,他被看做是Oracle?數據庫的一個大緩沖池,這里的數據可以被ORACLE的各個進程共用。其大小可以通過如下語句查看:?
SQL>?select?*?from?v$sga;?
NAME?VALUE?
--------------------?---------?
Fixed?Size?39816?
Variable?Size?259812784?
Database?Buffers?1.049E+09?
Redo?Buffers?327680?
更詳細的信息可以參考V$sgastat、V$buffer_pool?
主要包括以下幾個部分:?
a、?共享池(Shared?pool)?
共享池是SGA中最關鍵的內存片段,特別是在性能和可伸縮性上。一個太小的共享池會扼殺性能,使系統停止,太大的共享池也會有同樣的效果,將會消耗大量的CPU來管理這個共享池。不正確的使用共享池只會帶來災難。共享池主要又可以分為以下兩個部分:?
·SQL語句緩沖(Library?Cache)?
當一個用戶提交一個SQL語句,Oracle會將這句SQL進行分析(parse),這個過程類似于編譯,會耗費相對較多的時間。在分析完這個SQL,Oracle會把他的分析結果給保存在Shared?pool的Library?Cache中,當數據庫第二次執(zhí)行該SQL時,Oracle自動跳過這個分析過程,從而減少了系統運行的時間。這也是為什么第一次運行的SQL?比第二次運行的SQL要慢一點的原因。?
下面舉例說明parse的時間?
SQL>?select?count(*)?fromscpass?;?
COUNT(*)?
----------?
243?
Elapsed:?00:00:00.08?
這是在Share_pool?和Data?buffer?都沒有數據緩?
沖區(qū)的情況下所用的時間?
SQL>?alter?system?flush?SHARED_POOL;?
System?altered.?
清空Share_pool,保留Data?buffer?
SQL>?select?count(*)?from?scpass?;?
COUNT(*)?
----------?
243?
Elapsed:?00:00:00.02?
SQL>?select?count(*)?from?scpass?;?
COUNT(*)?
----------?
243?
Elapsed:?00:00:00.00?
從兩句SQL?的時間差上可以看出該SQL?的Parse?時間約為00:00:00.02?
對于保存在共享池中的SQL語句,可以從V$Sqltext、v$Sqlarea中查詢到,對于編程者來說,要盡量提高語句的重用率,減少語句的分析時間。一個設計的差的應用程序可以毀掉整個數據庫的Share?pool,提高SQL語句的重用率必須先養(yǎng)成良好的變成習慣,盡量使用Bind變量。?
·數據字典緩沖區(qū)(Data?Dictionary?Cache)?
顯而易見,數據字典緩沖區(qū)是ORACLE特地為數據字典準備的一塊緩沖池,供ORACLE內部使用,沒有什么可以說的。?
b、塊緩沖區(qū)高速緩存(Database?Buffer?Cache)?
這些緩沖是對應所有數據文件中的一些被使用到的數據塊。讓他們能夠在內存中進行?操作。在這個級別里沒有系統文件,,戶數據文件,臨時數據文件,回滾段文件之分。也就是任何文件的數據塊都有可能被緩沖。數據庫的任何修改都在該緩沖里完成,并由DBWR進程將修改后的數據寫入磁盤。?
這個緩沖區(qū)的塊基本上在兩個不同的列表中管理。一個是塊的“臟”表(Dirty?List),需要用數據庫塊的書寫器(DBWR)來寫入,另外一個是不臟的塊的列表(Free?List),一般的情況下,是使用最近最少使用(Least?Recently?Used,LRU)算法來管理。?
塊緩沖區(qū)高速緩存又可以細分為以下三個部分(Default?pool,Keep?pool,Recycle?pool)。如果不是人為設置初始化參數(Init.ora),ORACLE將默認為Default?pool。?
由于?操作系統尋址能力的限制,不通過特殊設置,在32位的系統上,塊緩沖區(qū)高速緩存最大可以達到1.7G,在64位系統上,塊緩沖區(qū)高速緩存最大可以達到10G。?
c、重做日志緩沖區(qū)(Redo?log?buffer)?
重做日志文件的緩沖區(qū),對數據庫的任何修改都按順序被記錄在該緩沖,然后由LGWR進程將它寫入磁盤。這些修改信息可能是DML語句,如(Insert,Update,Delete),或DDL語句,如(Create,Alter,Drop等)。?
重做日志緩沖區(qū)的存在是因為內存到內存的?操作比較內存到硬盤的速度快很多,所以重作日志緩沖區(qū)可以加快數據庫的?操作速度,但是考慮的數據庫的一致性與可恢復性,數據在重做日志緩沖區(qū)中的滯留時間不會很長。所以重作日志緩沖區(qū)一般都很小,大于3M之后的重作日志緩沖區(qū)已經沒有太大的實際意義。?
d、Java程序緩沖區(qū)(Java?Pool)?
Java?的程序區(qū),Oracle?8I?以后,Oracle?在內核中加入了對Java的支持。該程序緩沖區(qū)就是為Java?程序保留的。如果不用Java程序沒有必要改變該緩沖區(qū)的默認大小。?
e、大池(Large?Pool)?
大池的得名不是因為大,而是因為它用來分配大塊的內存,處理比共享池更大的內存,在8.0開始引入。?
下面對象使用大池:?
·MTS——在SGA的Large?Pool中分配UGA?
·語句的并行查詢(Parallel?Executeion?of?Statements)——允許進程間消息緩沖區(qū)的分配,用來協調并行查詢服務器?
·備份(Backup)——用于RMAN磁盤I/O緩存?
4、后臺進程(Background?process)?
后臺進程是Oracle的程序,用來管理數據庫的讀寫,恢復和監(jiān)視等工作。Server?Process主要是通過他和user?process進行聯系和溝通,并由他和user?process進行數據的交換。在Unix機器上,Oracle后臺進程相對于操作系統進程,也就是說,一個Oracle后臺進程將啟動一個操作系統進程;在Windows機器上,Oracle后臺進程相對于操作系統線程,打開任務管理器,我們只能看到一個ORACLE.EXE的進程,但是通過另外的工具,就可以看到包含在這里進程中的線程。?
在Unix上可以通過如下方法查看后臺進程:?
ps?–ef?|?grep?ora_?
#?ps?-ef?|?grep?ora_?|?grep?XCLUAT?
oracle?29431?1?0?Sep?02???2:02?ora_dbwr_SID?
oracle?29444?1?0?Sep?02???0:03?ora_ckpt_SID?
oracle?29448?1?0?Sep?02???2:42?ora_smon_SID?
oracle?29442?1?0?Sep?02???3:25?ora_lgwr_SID?
oracle?29427?1?0?Sep?02???0:01?ora_pmon_SID?
a、Oracle系統有5?個基本進程他們是?
DBWR(數據文件寫入進程)?
LGWR(日志文件寫入進程)?
SMON(系統監(jiān)護進程)?
PMON(用戶進程監(jiān)護進程)?
CKPT(檢查點進程,同步數據文件,?日志文件,控制文件)?
b、DBWR?
將修改過的數據緩沖區(qū)的數據寫入對應數據文件?
維護系統內的空緩沖區(qū)?
這里指出幾個容易錯誤的概念:?
·當一個更新提交后,DBWR把數據寫到磁盤并返回給用戶提交完成.?
·DBWR會觸發(fā)CKPT?后臺進程?
·DBWR不會觸發(fā)LGWR?進程?
上面的概念都是錯誤的.?
DBWR是一個很底層的工作進程,他批量的把緩沖區(qū)的數據寫入磁盤。和任何前臺用戶的進程幾乎沒有什么關系,也不受他們的控制。至于DBWR會不會觸發(fā)LGWR和CKPT進程,我們將在下面幾節(jié)里討論。?
DBWR工作的主要條件如下?
·DBWR?超時?
·系統中沒有多的空緩沖區(qū)用來存放數據?
·CKPT?進程觸發(fā)DBWR?等?
c、LGWR?
將重做日志緩沖區(qū)的數據寫入重做日志文件,LGWR是一個必須和前臺用戶進程通信的進程。當數據被修改的時候,系統會產生一個重做日志并記錄在重做日志緩沖區(qū)內。這個重做日志可以類似的認為是以下的一個結構:?
SCN=000000001000?
數據塊ID?
對象ID=0801?
數據行=02?
修改后的數據=0011?
提交的時候,LGWR必須將被修改的數據的重做日志緩沖區(qū)內數據寫入日志數據文件,然后再通知前臺進程提交成功,并由前臺進程通知用戶。從這點可以看出LGWR承擔了維護系統數據完整性的任務。?
LGWR?工作的主要條件如下?
·用戶提交?
·有1/3?重做日志緩沖區(qū)未被寫入磁盤?
·有大于1M?重做日志緩沖區(qū)未被寫入磁盤?
·超時?
·DBWR需要寫入的數據的SCN號大于LGWR?記錄的SCN號,DBWR?觸發(fā)LGWR寫入?
d、SMON?
工作主要包含?
????·清除臨時空間?
????·在系統啟動時,完成系統實例恢復?
????·聚結空閑空間?
????·從不可用的文件中恢復事務的活動?
????·OPS中失敗節(jié)點的實例恢復?
????·清除OBJ$表?
????·縮減回滾段?
????·使回滾段脫機?
e、PMON?
主要用于清除失效的用戶進程,釋放用戶進程所用的資源。如PMON將回滾未提交的工作,釋放鎖,釋放分配給失敗進程的SGA資源。?
f、CKPT?
同步數據文件,日志文件和控制文件,由于DBWR/LGWR的工作原理,造成了數據文件,日志文件,控制文件的不一至,這就需要CKPT進程來同步。CKPT會更新數據文件/控制文件的頭信息。?
CKPT工作的主要條件如下?
·在日志切換的時候?
·數據庫用immediate?,transaction?,?normal?選項shutdown?數據庫的時候?
·根據初始話文件LOG_CHECKPOINT_INTERVAL、LOG_CHECKPOINT_TIMEOUT、FAST_START_IO_TARGET?的設置的數值來確定?
·用戶觸發(fā)?
以下進程的啟動需要手工配置?
g、ARCH?
當數據庫以歸檔方式運行的時候,Oracle會啟動ARCH進程,當重做日志文件被寫滿時,日志文件進行切換,舊的重做日志文件就被ARCH進程復制到一個/多個特定的目錄/遠程機器。這些被復制的重做日志文件被叫做歸檔日志文件。?
h、RECO?
負責解決分布事物中的故障。Oracle可以連接遠程的多個數據庫,當由于網絡問題,有些事物處于懸而未決的狀態(tài)。RECO進程試圖建立與遠程服務器的通信,當故障消除后,RECO進程自動解決所有懸而未決的會話。?
i、服務進程Server?Process?
服務進程的分類?
·專用服務進程(Dedicated?Server?Process)?
一個服務進程對應一個用戶進程?
·共享服務進程(MultiTreaded?Server?Process)?
一個服務進程對應多個用戶進程,輪流為用戶進程服務。?
PGA?&?UGA?
PGA?=?Process?Global?Area?
UGA?=?User?Global?Area?
他保存了用戶的變量、權限、堆棧、排序空間等用戶信息,對于專用服務器進程,UGA在PGA中分配。對于多線程進程,UGA在Large?pool中分配。?
j、用戶進程User?Process?
在客戶端,將用戶的SQL?語句傳遞給服務進程?
5、一個貫穿數據庫全局的概念----系統改變號SCN(System?Change?Number)?
系統改變號,一個由系統內部維護的序列號。當系統需要更新的時候自動增加,他是系統中維持數據的一致性和順序恢復的重要標志。?
a.?查詢語句不會使SCN增加,就算是同時發(fā)生的更新,數據庫內部對應的SCN也是不同的。這樣一來就保證了數據恢復時候的順序。?
b.?維持數據的一致性,當一個查詢執(zhí)行的時候,他會先從系統中得到一個當前的SCN號,在他查找數據的同時,他會檢查每個數據行和他對應的SCN號,只有那些不比他的SCN號大的行才能從對應用戶數據文件的緩沖區(qū)內取出,而那些大于他SCN號的行,就應該從回滾段數據文件的緩沖中取出。?
實例分析:?
一個查詢返回以下5?行?
ID?Name?
------------------------?
1?ShangHai?
2?Beijing?
3?Gugangzhou?
4?ShenZhen?
5?HanZhou?
用戶A從12:00開始運行,到12:05結束在12:01用戶B執(zhí)行了一條Update語句,更新了ID是2的那條記錄把Beijing該成了Tianjing.并提交,這時候用戶A?的那個查詢是不會出現Tianjing的記錄。12:00查詢時候的SCN是N然后用戶B的更新使得系統的SCN變成N+1當用戶A查詢到ID=2的記錄的時候發(fā)現他的SCN已經大于查詢開始時候的SCN,他就會在回滾段數據緩沖中找到SCN=N的那條記錄,并把它返回。?
??
二、ORACLE?數據庫?
ORACLE數據庫的組成——物理操作系統文件的集合。主要包括以下幾種。?
1、控制文件(參數文件init.ora記錄了控制文件的位置)?
控制文件包括如下主要信息?
·數據庫的名字,檢查點信息,數據庫創(chuàng)建的時間戳?
·所有的數據文件,聯機日志文件,歸檔日志文件信息?
·備份信息等?
有了這些信息,Oracle就知道那些文件是數據文件,現在的重做日志文件是哪些,這些都是系統啟動和運行的基本條件,所以他是Oracle運行的根本。如果沒有控制文件系統是不可能啟動的。控制文件是非常重要的,一般采用多個鏡相復制來保護控制文件,或采用RAID來保護控制文件。控制文件的丟失,將使數據庫的恢復變的很復雜。?
控制文件信息可以從V$Controlfile中查詢獲得?
??
2、數據文件(數據文件的詳細信息記載在控制文件中)?
可以通過如下方式查看數據文件?
SQL>?select?name?from?v$datafile;?
NAME?
---------------------------------------------?
/u05/dbf/PROD/system_01.dbf?
/u06/dbf/PROD/temp_01.dbf?
/u04/dbf/PROD/users_01.dbf?
/u09/dbf/PROD/rbs_01.dbf?
/u06/dbf/PROD/applsys_indx_01.dbf?
/u05/dbf/PROD/applsys_data_01.dbf?
從以上可以看出,數據文件大致可以分為以下幾類:?
i.?系統數據文件(system_01.dbf)?
存放系統表和數據字典,一般不放用戶的數據,但是用戶腳本,如過程,函數,包等卻是保存在數據字典中的。?
名詞解釋:數據字典?
數據字典是一些系統表或視圖,他存放系統的信息,他包括數據庫版本,數據文件信息,表與索引等段信息,系統的運行狀態(tài)等各種和系統有關的信息和用戶腳本信息。數據庫管理員可以通過對數據字典的查詢,就可以了解到Oracle的運行狀態(tài)。?
ii.?回滾段文件(rbs_01.dbf)?
如果數據庫進行對數據的修改,那么就必須使用回滾段,回滾段是用來臨時存放修改前的數據(Before?Image)。回滾段通常都放在一個單獨的表空間上(回滾表空間),避免表空間碎片化,這個表空間包含的數據文件就是回滾數據文件。?
iii.?臨時數據文件(temp_01.dbf)?
主要存放用戶的排序等臨時數據,與回滾段相似,臨時段也容易引起表空間碎片化,而且沒有辦法在一個永久表空間上開辟臨時段,所以就必須有一個臨時表空間,它所包含的數據文件就是臨時數據文件,主要用于不能在內存上進行的排序操作。我們必須為用戶指定一個臨時表空間。?
iv.?用戶數據文件(/applsys_data_01.dbf?,applsys_indx_01.dbf)?
存放用戶數據,這里列舉了兩類常見的用戶型數據,一般數據和索引數據,一般來說,如果條件許可的話,可以考慮放在不同的磁盤上。?
3、重做日志文件(聯機重做日志)?
用戶對數據庫進行的任何操作都會記錄在重做日志文件。在了解重做日志之前必須了解重做日志的兩個概念,重做日志組和重做日志組成員(Member),一個數據庫中至少要有兩個日志組文件,一組寫完后再寫另一組,即輪流寫。每個日志組中至少有一個日志成員,一個日志組中的多個日志成員是鏡相關系,有利于日志文件的保護,因為日志文件的損壞,特別是當前聯機日志的損壞,對數據庫的影響是巨大的。?
聯機日志組的交換過程叫做切換,需要特別注意的是,日志切換在一個優(yōu)化效果不好的數據庫中會引起臨時的“掛起”。掛起大致有兩種情況:?
·在歸檔情況下,需要歸檔的日志來不及歸檔,而聯機日志又需要被重新利用?
·檢查點事件還沒有完成(日志切換引起檢查點),而聯機日志需要被重新利用?
解決這種問題的常用手段是:?
i.增加日志組?
ii.增大日志文件成員大小?
通過v$log可以查看日志組,v$logfile可以查看具體的成員文件。?
4、歸檔日志文件?
Oracle可以運行在兩種模式之中,歸檔模式和不歸檔模式。如果不用歸檔模式,當然,你就不會有歸檔日志,但是,你的系統將不會是一個實用系統,特別是不能用于生產系統,因為你可能會丟失數據。但是在歸檔模式中,為了保存用戶的所有修改,在重做日志文件切換后和被覆蓋之間系統將他們另外保存成一組連續(xù)的文件系列,該文件系列就是歸檔日志文件。?
有人或許會說,歸檔日志文件占領我大量的硬盤空間,其實,具體想一想,你是愿意浪費一點磁盤空間來保護你的數據,還是愿意丟失你的數據呢?顯而義見,我們需要保證我們的數據的安全性。其實,歸檔并不是一直占領你的磁盤空間,你可以把她備份到磁帶上,或則刪除上一次完整備份前的所有日志文件。?
5、初始化參數文件?
initSID.ora或init.ora文件,因為版本的不一樣,其位置也可能會不一樣。在8i中,通常位于$ORACLE_HOME/admin/<SID>/Pfile下?
初始化文件記載了許多數據庫的啟動參數,如內存,控制文件,進程數等,在數據庫啟動的時候加載(Nomount時加載),初始化文件記錄了很多重要參數,對數據庫的性能影響很大,如果不是很了解,不要輕易亂改寫,否則會引起數據庫性能下降。?
6、其他文件?
i?.?密碼文件?
用于Oracle?的具有sysdba權限用戶的認證.?
ii.?日志文件?
·報警日志文件(alert.log或alrt<SID>.ora)?
記錄數據庫啟動,關閉和一些重要的出錯信息。數據庫管理員應該經常檢查這個文件,并對出現的問題作出即使的反應。你可以通過以下SQL?找到他的路徑select?value?from?v$PARAMETER?where?name?='background_dump_dest';?
·后臺或用戶跟蹤文件?
系統進程或用戶進程出錯前寫入的信息,一般不可能讀懂,可以通過ORACLE的TKPROF工具轉化為可以讀懂的格式。對于系統進程產生的跟蹤文件與報警日志文件的路徑一樣,用戶跟蹤文件的路徑,你可以通過以下SQL找到他的路徑select?value?from?v$PARAMETER?where?name?='user_dump_dest';?
??
三、ORACLE邏輯結構?
1、?表空間(tablespace)?
表空間是數據庫中的基本邏輯結構,一系列數據文件的集合。一個表空間可以包含多個數據文件,但是一個數據文件只能屬于一個表空間。?
2、?段(Segment)?
段是對象在數據庫中占用的空間,雖然段和數據庫對象是一一對應的,但段是從數據庫存儲的角度來看的。一個段只能屬于一個表空間,當然一個表空間可以有多個段。?
表空間和數據文件是物理存儲上的一對多的關系,表空間和段是邏輯存儲上的一對多的關系,段不直接和數據文件發(fā)生關系。一個段可以屬于多個數據文件,關于段可以指定擴展到哪個數據文件上面。?
段基本可以分為以下四種?
·數據段(Data?Segment)?
·索引段(Index?Segment)?
·回滾段(Rollback?Segment)?
·臨時段(Temporary?Segment)?
3、區(qū)間(Extent)?
關于Extent的翻譯有多種解釋,有的譯作擴展,有的譯作盤區(qū),我這里通常譯為區(qū)間。在一個段中可以存在多個區(qū)間,區(qū)間是為數據一次性預留的一個較大的存儲空間,直到那個區(qū)間被用滿,數據庫會繼續(xù)申請一個新的預留存儲空間,即新的區(qū)間,一直到段的最大區(qū)間數(Max?Extent)或沒有可用的磁盤空間可以申請。?
在ORACLE8i以上版本,理論上一個段可以無窮個區(qū)間,但是多個區(qū)間對ORACLE卻是有性能影響的,ORACLE建議把數據分布在盡量少的區(qū)間上,以減少ORACLE的管理與磁頭的移動。?
4、Oracle數據塊(Block)?
ORACLE最基本的存儲單位,他是OS數據塊的整數倍。ORACLE的操作都是以塊為基本單位,一個區(qū)間可以包含多個塊(如果區(qū)間大小不是塊大小的整數倍,ORACLE實際也擴展到塊的整數倍)。?
5、基本表空間介紹?
a.?系統表空間?
主要存放數據字典和內部系統表基表?
查看數據數據字典的SQL?
select?*?from?dict?
查看內部系統表的SQL?
select?*?from?v$fixed_view_definition?
DBA對系統的系統表中的數據字典必須有一個很深刻的了解,他們必須準備一些基礎的SQL語句,通過這些SQL可以立即了解系統的狀況和數據庫的狀態(tài),這些基本的SQL包括?
系統的剩余空間?
系統的SGA??
狀態(tài)系統的等待?
用戶的權限?
當前的用戶鎖?
緩沖區(qū)的使用狀況等?
在成為DBA?的道路上我們不建議你過分的依賴于OEM/Quest?等優(yōu)秀的數據庫管理工具,因為他們不利于你對數據數據字典的理解,SQL語句可以完成幾乎全部的數據庫管理工作。?
大量的讀少量的寫是該表空間的一個顯著的特點。?
b.?臨時表空間.?
臨時表空間顧名思義是用來存放臨時數據的,例如排序操作的臨時空間,他的空間會在下次系統啟動的時候全部被釋放。?
c.?回滾段表空間?
i.?回滾段在系統中的作用?
當數據庫進行更新插入刪除等操作的時候,新的數據被更新到原來的數據文件,而舊的數據(Before?Image)就被放到回滾段中,如果數據需要回滾,那么可以從回滾段將數據再復制到數據文件中。來完成數據的回滾。在系統恢復的時候,?回滾段可以用來回滾沒有被commit?的數據,解決系統的一直性讀。?
???????回滾段在什么情況下都是大量的寫,一般是少量讀,因此建議把回滾段單獨出來放在一個單獨的設備(如單獨的磁盤或RAID),以減少磁盤的IO爭用。??
ii.?回滾段的工作方式?
·一個回滾表空間可以被劃分成多個回滾段.?
·一個回滾段可以保存多個會話的數據.?
·回滾段是一個圓形的數據模型?
假設回滾段由4?個區(qū)間組成,他們的使用順序就是區(qū)間1à區(qū)間2à區(qū)間3à區(qū)間4à區(qū)間1。也就是說,區(qū)間是可以循環(huán)使用的,當區(qū)間4到區(qū)間1的時候,區(qū)間1里面的會話還沒有結束,?區(qū)間4用完后就不能再用區(qū)間1,這時系統必須分配區(qū)間5,來繼續(xù)為其他會話服務服務。?
我們分析一個Update?語句的完成?
①.?用戶提交一個Update?語句?
②.?Server?Process?檢查內存緩沖.?
如果沒有該數據塊的緩沖,則從磁盤讀入?
i.?如果沒有內存的有效空間,DBWR被啟動將未寫入磁盤的臟緩沖寫入磁盤?
ii.?如果有有效空間,則讀入?
③.?在緩沖內更新數據?
i.?申請一個回滾段入口,將舊數據寫如回滾段?
ii.?加鎖并更新數據?
iii.?并在同時將修改記錄在Redo?log?buffer中?
④.?用戶提交一個Commit?語句?
i.?SCN增加?
ii.?將Redo?log?buffer?寫入Redo?log?file?
iii.?返回用戶Commit?完成?
??
四、ORACLE核心初探?
1、LRU?算法和數據緩沖區(qū)?
我們知道Oracle?數據庫的文件大小遠遠大于Oracle?的所擁有的內存區(qū)域SGA,LRU就是一種盡可能將常用的數據保留在內存的算法。當數據庫需要一個數據緩沖區(qū),他會從數據庫緩沖區(qū)的LRU隊列的尾部找一個空閑的緩沖,將一個數據塊讀入,然后數據庫會把這個緩沖區(qū)放到LRU?隊列的中部,如果該緩沖被其他程序用到的話,那么他會往隊列的頭上移動,如果這個緩沖沒有被其他程序用到,并且沒有被修改過,那么他會慢慢的移動到LRU?隊列的尾部,最終被認為是空緩沖區(qū)被其他數據塊所覆蓋。一旦這個緩沖區(qū)被修改過DBWR把他從LRU隊列中移出,放到LRUW?隊列(也叫贓緩沖區(qū))中,等待DBWR把他們批量寫入數據文件,然后再把他們的緩沖區(qū)連接到LRU隊列的尾部,周而復始的工作。?
理解HASH算法,為了提高速度Oracle在設計中采用了大量的HASH算法,這里我們講一下HASH算法的理論知識,在以后的閱讀中會對Oracle有更好的理解。HASH是一種以空間換取時間的做法。假如我有100萬條數據,以隊列的方式存儲,如果我要從里面找一條數據,那么我要從頭開始找,我所需要的空間是100萬個存儲單元,如果我用HASH的方法來存儲,我把存儲空間劃分為1000*2000的數組,把100萬個數據分別按照如下規(guī)則添入該數組:?
1.?定義一個函數,使得每條數據對應一個0-999的值?
2.?把該行記錄存儲在以函數返回值為下標的數組里?
3.?我們稱該函數為hash?函數f(row).?hash?函數的返回值為hash?值.數組為?
hash?數組HashArray[n][m].?
即有下列公式?
find?a?unused?buffer?in?HashArray[f(row)][?]?
HashArray[f(row)][?]?=?row;?
這樣,當我們需要一個行時候我們只需簡單的計算該行的hash值,然后到下標為hash值的hash數組里找就可以了。即使用最簡單的方法也可以很快的找到?
For?(I=1;I<=2000;?I?++)?
If?(HashArray[f(row)][I]?==?row?)?return;?
Next?
當然HASH算法還是很復雜的,這里只是一個最最簡單的例子。如果大家有興趣可以看看有關數據結構的資料,這里就不具體展開了。?
??
2、LATCH(Oracle內部鎖)?
有許多人問我Latch和Lock?的區(qū)別,其實很簡單,Latch是Oracle內部的Lock,他負責更為細小的內部讀寫,比如Oracle要把用戶更新的數據寫入緩沖區(qū),這時候Oracle就會在該緩沖區(qū)上加上latch,用來防止DBWR把他寫出到磁盤,因為如果沒有這個Latch,DBWR會把一半新一半老沒有用的數據寫到磁盤上。?
??
五、常見問題?
1、實例和SID的關系是什么??
經常有人問SID?是什么?在Oracle?系統中SID?是一個經常出現的變量,如環(huán)境變量ORACLE_SID,?初始化文件initSID.ora,那究竟什么是SID?呢?其實SID?就是Oracle?實例的標識,不同的SID?對應不同的內存緩沖(SGA)和不同的后臺進程。這樣一來我們就可以得當在一臺物理的服務器上可以有多個SID?的數據庫實例。?
2、Oracle數據庫和實例的關系是什么??
數據庫是由物理文件和存取數據文件的實例組成,當存取數據文件的實例是一個的時候,數據庫被稱做單節(jié)點數據庫。這是我們看到的最多的數據庫形式。當然還有一種多節(jié)點數據庫,就是一個以上的實例共同訪問一個數據庫(或者說共同訪問一組數據文件),?更好的提供穩(wěn)定性和并行處理能力。這在8i中被稱為OPS(Oracle?Parallel?Server?),在Oracle9i?中被稱為RAC(real?application?cluster)。在這種數據庫中。兩個/多個實例分別在不同服務器上,所有Oracle?數據文件在共享的磁盤陣列上,多個服務器上的實例可以同時工作,他們通過一個內部的網絡進行通信。如果一臺服務器不能提供服務的話,另一臺會接管它的工作,特別是在關鍵的業(yè)務有很大的潛力。?
3、在運行的數據庫中數據文件中是不是可能存在沒有被提交的數據??
這是可能存在的,因為用戶數據文件的數據是由DBWR寫入的,DBWR是一個很底層的后臺進程,不負責與用戶交互。用戶的交互是由LGWR完成的。?
4、在問題3中,如果存在沒有寫入的數據,那么機器突然斷電,數據完整性會不會損壞??
不會的,因為數據庫的完整性是LGWR來保證的,而且ORACLE保證了DBWR寫入數據文件的任何修改已經被記錄在重做日志文件中。當系統再次啟動的時候,通過讀取重做日志文件就可以知道那些數據沒有被提交。這時候ORACLE?會自動回滾那些數據。所以說聯機日志的損壞,特別是當前聯機日志的損壞,對數據庫的影響是巨大的,可能會導致數據庫的不完整。?
5、數據文件損壞會丟失數據嗎??
可以這么說,如果你有備份和歸檔,就不會。因為所有對數據修改的記錄都在重做日志中有記錄,所以不會丟失數據,你只要恢復以前的備份再用歸檔日志文件恢復和當前的在線重做日志就可以恢復所有數據。?
6、在線重做日志損壞會丟失數據嗎??
以上說了,在線日志對數據庫的損壞是極大的,所以不僅可能丟失數據,還可能引起數據庫的不同步。在重做日志中的所有commit的記錄都會丟失,這也是Oracle?為什么要對在線重做日志文件做鏡像的原因。任何的數據丟失都是不允許的。?
7、我在事務能不能指定不寫回滾段??
不可以的,寫回滾段是ORACLE保證一致性讀和事務一致性的根本。回滾段是高寫入段,建議把它放到單獨的設備上來。?
對于DDL語句,如DROP,TRUNCATE卻可以不寫回滾段(沒有UNDO信息),所以對于整個表的刪除,如果數據量比較大,建議用Truncate?Table的方法。?
不寫聯機日志也是不可能的,但可以在某些特定操作中,可以寫很少的聯機日志,如以NOLOGGING的方式通過Create?table?tablename?as?select創(chuàng)建表,或以Append的方式Insert數據到表,或直接載入等操作。?
六、小結?
這里,我們了解了實例和數據庫的關系,一個數據庫可以有多個實例,但是一個實例卻不可能對應多個數據庫,在一般的情況下,我們都是用的單節(jié)點數據庫,即一個實例僅僅對應一個數據庫。?
我們了解了ORACLE實例的組成,包括內存和后臺進程,進一步解釋了SGA的組成與SGA的作用,并分析了語句重用的好處。在后臺進程中,重要的闡述了DBWR與LGWR,其中DBWR是一個底層的由ORACLE控制的后臺進程,而LGWR負責與用戶交互.?
在ORACLE數據庫中,我們重要闡述了數據庫的物理與邏輯結構,在物理結構中,需要注意四類以下文件:控制文件,聯機日志,數據文件與參數文件。在邏輯結構中,需要清楚每個邏輯結構的關系,從大到小的順序為:表空間à段à區(qū)間à塊。?
最后,簡單的描敘了兩個ORACLE的核心內容,LRU算法與LATCH,并初步闡述了HASH算法的相關內容。有關ORACLE更多的核心內容,可以參考相關資料。
總結
以上是生活随笔為你收集整理的oracle体系结构剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用ASP.NET2.0向导控件一步步建
- 下一篇: 成功者网上创业的精华经验