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