主 題:
|
?
|
ORACLE
體系結構
(Architecture of ORACLE)
|
作 者:
|
?
|
penitent (只取一瓢)
|
等 級:
|
?
|
|
信
譽
值:
|
?
|
100
|
所屬論壇:
|
?
|
Oracle
高級技術
|
問題點數:
|
?
|
0
|
回復次數:
|
?
|
12
|
發表時間:
|
?
|
2003-03-31 21:32:
|
???
很多人和我一樣,大楷都是從
SQL Server
轉過來的,可能是受
MS
的影響太深,老想著用
SQL Server
的方法來解決
ORACLE
的問題,這就是一個極大的失誤,比如有人就老喜歡用那個
OEM
,那個我一直認為是
ORACLE
的糟粕的一個代表,
ORACLE
的精髓是代碼的管理,任何管理、備份、恢復都可以通過代碼或腳本實現。比如還有的人就喜歡
SQL Server
過程中能直接寫
select
語句,認為
ORACLE
必須要能做,有人認為
SQL SERVER
的過程能執行
DDL
語句,那
ORACLE
也必須要這樣……誠然,我不是承認不可以,但是很多的很多的這一切,就是你實現了,卻是
ORACLE
強烈反對的,因為它們對
ORACLE
的性能可能有很大的影響。
???
我想,要學好
ORACLE
,就必須腳踏實地,一步一步來,你可以拿兩個數據庫來比較,但是不要想著關系型數據庫都是一樣的,它們是有差別的,或多或少,一個簡單的例子,在
SQL Server
中,一個表的修改是以頁面級來鎖定的,對表的修改是阻塞讀操作的(如
Select
),所以
SQL Server
的鎖是非常昂貴的,如果不是特別指定,一個語句就是一個事務。在
ORACLE
中,這一切都變了,
ORACLE
可以提供最小的行級鎖,所有對表的鎖定不影響
Select
查詢,在
ORACLE
中,鎖的資源占用是非常小的,所以
ORACLE
默認開啟事務,直到你提交或回滾。
???
我學
ORACLE
也就兩年時間,到現在專職做
ORACLE
管理和
ORACLE
數據倉庫,也是自己慢慢走過來的,我其實也沒有得到高人指點,就是自己慢慢啃書,慢慢查資料。論壇可以用來交流,但是想讓它讓你有很大進步,可能性不大,畢竟,論壇上面系統性的東西太少。要想做一個好的
DBA
,是不容易的,有人總結了
DBA 10
點該做的和不該做的。
> #1 - Do Maintain your Expertise
> #2 - Do Use the DBMS_STATS Package to Collect Statistics
> #3 - Do Use Bind Variables
> #4 - Do Put your Production Database in ARCHIVELOG Mode
> #5 - Do Use Locally Managed Tablespaces
> #6 - Do Monitor Your Database
> #7 - Do Practice Recoveries
> #8 - Do Get Involved with User Groups and Other Resources
> #9 - Do Establish Standards and Change Control Processes
> #10 - Do Think Ahead
?
> Oracle Database Top 10 Don'ts
> #1 - Don't Waste Time Re-Organizing Your Databases
> #2 - Don't Use .Log or Other Common Extensions For Your Database File Names
> #3 - Don't Leave Your Database Open To Attack
> #4 - Don't Decide Against Hot Backups
> #5 - Don't Use ASSM
> #6 - Don't Forget the 80/20 Rule
> #7 - Don't Stack Views
> #8 - Don't Be a Normalization Bigot
> #9 - Don't Forget to Document Everything
> #10 - Do Not Use Products You are Not Licensed For.
???? CSDN
上的專職從事數據庫管理的可能很少,也就導致了這里很多人的問題都是在開發上面,當然,我不是要求大家學管理,就是開發,也需要對數據庫理解,半懂不懂的搞開發,最可能的后果,可能就是項目的失敗,而這是一個程序員的恥辱。
????
正因為
CSDN
的這種特殊情況,很多高手都不愿意來這里,我問其原因,回答很簡單,
CSDN
只能讓我退步,我去干什么,大家也都清楚,現在是一個信息化的時代,不是不進則退了,是進步慢也是退步的時代了。
????
今天就寫這么多,下面開始轉入正文,因為時間倉促,多少可能有些筆誤或錯誤,也就希望大家指正,在以后的時間里,我會定期的寫這么一些文章,希望大家有所收獲,我的下一篇文章計劃是“
ORACLE
的備份策應”。
?????
此文不經許可,不可轉載,如有必要,也需要注明出處!
-------------------------------------------------------------------------
?
?????????????????????????????????
概要
在本章里你可以了解以下內容
-
ORACLE
實例——包括內存結構與后臺進程
-
?ORACLE
數據庫——物理操作系統文件的集合
-
了解內存結構的組成
-
了解后臺進程的作用
-
了解數據庫的物理文件
-
?解釋各種邏輯結構
?
?
一、
ORACLE
事例
1
、
ORACLE
實例
System Global Area(SGA)
和
Background Process
被成為數據庫的實例。
2
、
ORACLE
數據庫
一系列物理文件的集合(數據文件,控制文件,聯機日志,參數文件等)
3
、系統全局共享區
System Global Area(SGA)
System Global Area
是一塊巨大的共享內存區域,他被看做是
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
中,當數據庫第二次執行該
SQL
時,
Oracle
自動跳過這個分析過程,從而減少了系統運行的時間。這也是為什么第一次運行的
SQL
比第二次運行的
SQL
要慢一點的原因。
下面舉例說明
parse
的時間
SQL> select count(*) fromscpass ;
COUNT(*)
----------
243
Elapsed: 00:00:00.08
這是在
Share_pool
和
Data buffer
都沒有數據緩
沖區的情況下所用的時間
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
語句的重用率必須先養成良好的變成習慣,盡量使用
Bind
變量。
·數據字典緩沖區
(Data Dictionary Cache)
顯而易見,數據字典緩沖區是
ORACLE
特地為數據字典準備的一塊緩沖池,供
ORACLE
內部使用,沒有什么可以說的。
b
、塊緩沖區高速緩存
(Database Buffer Cache)
這些緩沖是對應所有數據文件中的一些被使用到的數據塊。讓他們能夠在內存中進行操作。在這個級別里沒有系統文件
,
,戶數據文件,臨時數據文件,回滾段文件之分。也就是任何文件的數據塊都有可能被緩沖。數據庫的任何修改都在該緩沖里完成,并由
DBWR
進程將修改后的數據寫入磁盤。
這個緩沖區的塊基本上在兩個不同的列表中管理。一個是塊的“臟”表
(Dirty List)
,需要用數據庫塊的書寫器
(DBWR)
來寫入,另外一個是不臟的塊的列表
(Free List)
,一般的情況下,是使用最近最少使用
(Least Recently Used,LRU)
算法來管理。
塊緩沖區高速緩存又可以細分為以下三個部分(
Default pool,Keep pool,Recycle pool
)。如果不是人為設置初始化參數
(Init.ora)
,
ORACLE
將默認為
Default pool
。
由于操作系統尋址能力的限制,不通過特殊設置,在
32
位的系統上,塊緩沖區高速緩存最大可以達到
1.7G
,在
64
位系統上,塊緩沖區高速緩存最大可以達到
10G
。
c
、重做日志緩沖區
(Redo log buffer)
重做日志文件的緩沖區,對數據庫的任何修改都按順序被記錄在該緩沖,然后由
LGWR
進程將它寫入磁盤。這些修改信息可能是
DML
語句,如
(Insert,Update,Delete)
,或
DDL
語句,如
(Create,Alter,Drop
等
)
。
重做日志緩沖區的存在是因為內存到內存的操作比較內存到硬盤的速度快很多,所以重作日志緩沖區可以加快數據庫的操作速度,但是考慮的數據庫的一致性與可恢復性,數據在重做日志緩沖區中的滯留時間不會很長。所以重作日志緩沖區一般都很小,大于
3M
之后的重作日志緩沖區已經沒有太大的實際意義。
d
、
Java
程序緩沖區
(Java Pool)
Java
的程序區,
Oracle 8I
以后,
Oracle
在內核中加入了對
Java
的支持。該程序緩沖區就是為
Java
程序保留的。如果不用
Java
程序沒有必要改變該緩沖區的默認大小。
e
、大池
(Large Pool)
大池的得名不是因為大,而是因為它用來分配大塊的內存,處理比共享池更大的內存,在
8.0
開始引入。
下面對象使用大池:
·
MTS
——在
SGA
的
Large Pool
中分配
UGA
·語句的并行查詢
(Parallel Executeion of Statements)
——允許進程間消息緩沖區的分配,用來協調并行查詢服務器
·備份
(Backup)
——用于
RMAN
磁盤
I/O
緩存
4
、后臺進程
(Background process)
后臺進程是
Oracle
的程序,用來管理數據庫的讀寫,恢復和監視等工作。
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
個基本進程他們是
b
、
DBWR
將修改過的數據緩沖區的數據寫入對應數據文件
維護系統內的空緩沖區
這里指出幾個容易錯誤的概念
:
·當一個更新提交后
,DBWR
把數據寫到磁盤并返回給用戶提交完成
.
·
DBWR
會觸發
CKPT
后臺進程
·
DBWR
不會觸發
LGWR
進程
上面的概念都是錯誤的
.
DBWR
是一個很底層的工作進程,他批量的把緩沖區的數據寫入磁盤。和任何前臺用戶的進程幾乎沒有什么關系,也不受他們的控制。至于
DBWR
會不會觸發
LGWR
和
CKPT
進程,我們將在下面幾節里討論。
DBWR
工作的主要條件如下
·
DBWR
超時
·系統中沒有多的空緩沖區用來存放數據
·
CKPT
進程觸發
DBWR
等
c
、
LGWR
將重做日志緩沖區的數據寫入重做日志文件,
LGWR
是一個必須和前臺用戶進程通信的進程。當數據被修改的時候,系統會產生一個重做日志并記錄在重做日志緩沖區內。這個重做日志可以類似的認為是以下的一個結構
:
SCN=000000001000
數據塊
ID
對象
ID=0801
數據行
=02
修改后的數據
=0011
提交的時候,
LGWR
必須將被修改的數據的重做日志緩沖區內數據寫入日志數據文件,然后再通知前臺進程提交成功,并由前臺進程通知用戶。從這點可以看出
LGWR
承擔了維護系統數據完整性的任務。
LGWR
工作的主要條件如下
·用戶提交
·有
1/3
重做日志緩沖區未被寫入磁盤
·有大于
1M
重做日志緩沖區未被寫入磁盤
·超時
·
DBWR
需要寫入的數據的
SCN
號大于
LGWR
記錄的
SCN
號,
DBWR
觸發
LGWR
寫入
d
、
SMON
工作主要包含
??
·清除臨時空間
??
·在系統啟動時,完成系統實例恢復
??
·聚結空閑空間
??
·從不可用的文件中恢復事務的活動
??
·
OPS
中失敗節點的實例恢復
??
·清除
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
的設置的數值來確定
·用戶觸發
以下進程的啟動需要手工配置
g
、
ARCH
當數據庫以歸檔方式運行的時候,
Oracle
會啟動
ARCH
進程,當重做日志文件被寫滿時,日志文件進行切換,舊的重做日志文件就被
ARCH
進程復制到一個
/
多個特定的目錄
/
遠程機器。這些被復制的重做日志文件被叫做歸檔日志文件。
h
、
RECO
負責解決分布事物中的故障。
Oracle
可以連接遠程的多個數據庫,當由于網絡問題,有些事物處于懸而未決的狀態。
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
增加,就算是同時發生的更新,數據庫內部對應的
SCN
也是不同的。這樣一來就保證了數據恢復時候的順序。
b.
維持數據的一致性,當一個查詢執行的時候,他會先從系統中得到一個當前的
SCN
號,在他查找數據的同時,他會檢查每個數據行和他對應的
SCN
號,只有那些不比他的
SCN
號大的行才能從對應用戶數據文件的緩沖區內取出,而那些大于他
SCN
號的行,就應該從回滾段數據文件的緩沖中取出。
實例分析
:
一個查詢返回以下
5
行
ID Name
------------------------
1 ShangHai
2 Beijing
3 Gugangzhou
4 ShenZhen
5 HanZhou
用戶
A
從
12:00
開始運行,到
12:05
結束在
12:01
用戶
B
執行了一條
Update
語句,更新了
ID
是
2
的那條記錄把
Beijing
該成了
Tianjing.
并提交,這時候用戶
A
的那個查詢是不會出現
Tianjing
的記錄。
12:00
查詢時候的
SCN
是
N
然后用戶
B
的更新使得系統的
SCN
變成
N+1
當用戶
A
查詢到
ID=2
的記錄的時候發現他的
SCN
已經大于查詢開始時候的
SCN
,他就會在回滾段數據緩沖中找到
SCN=N
的那條記錄,并把它返回。
二、
ORACLE
數據庫
ORACLE
數據庫的組成——物理操作系統文件的集合。主要包括以下幾種。
1
、控制文件(參數文件
init.ora
記錄了控制文件的位置)
控制文件包括如下主要信息
·數據庫的名字,檢查點信息,數據庫創建的時間戳
·所有的數據文件,聯機日志文件,歸檔日志文件信息
·備份信息等
有了這些信息,
Oracle
就知道那些文件是數據文件,現在的重做日志文件是哪些,這些都是系統啟動和運行的基本條件,所以他是
Oracle
運行的根本。如果沒有控制文件系統是不可能啟動的??刂莆募欠浅V匾?,一般采用多個鏡相復制來保護控制文件,或采用
RAID
來保護控制文件??刂莆募膩G失,將使數據庫的恢復變的很復雜。
控制文件信息可以從
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)
存放系統表和數據字典,一般不放用戶的數據,但是用戶腳本,如過程,函數,包等卻是保存在數據字典中的。
名詞解釋:數據字典
數據字典是一些系統表或視圖,他存放系統的信息,他包括數據庫版本,數據文件信息,表與索引等段信息,系統的運行狀態等各種和系統有關的信息和用戶腳本信息。數據庫管理員可以通過對數據字典的查詢,就可以了解到
Oracle
的運行狀態。
ii.
回滾段文件
(rbs_01.dbf)
如果數據庫進行對數據的修改,那么就必須使用回滾段,回滾段是用來臨時存放修改前的數據
(Before Image)
。回滾段通常都放在一個單獨的表空間上(回滾表空間),避免表空間碎片化,這個表空間包含的數據文件就是回滾數據文件。
iii.
臨時數據文件
(temp_01.dbf)
主要存放用戶的排序等臨時數據,與回滾段相似,臨時段也容易引起表空間碎片化,而且沒有辦法在一個永久表空間上開辟臨時段,所以就必須有一個臨時表空間,它所包含的數據文件就是臨時數據文件,主要用于不能在內存上進行的排序操作。我們必須為用戶指定一個臨時表空間。
iv.
用戶數據文件
(/applsys_data_01.dbf ,applsys_indx_01.dbf)
存放用戶數據,這里列舉了兩類常見的用戶型數據,一般數據和索引數據,一般來說,如果條件許可的話,可以考慮放在不同的磁盤上。
3
、重做日志文件(聯機重做日志)
用戶對數據庫進行的任何操作都會記錄在重做日志文件。在了解重做日志之前必須了解重做日志的兩個概念,重做日志組和重做日志組成員
(Member)
,一個數據庫中至少要有兩個日志組文件,一組寫完后再寫另一組,即輪流寫。每個日志組中至少有一個日志成員,一個日志組中的多個日志成員是鏡相關系,有利于日志文件的保護,因為日志文件的損壞,特別是當前聯機日志的損壞,對數據庫的影響是巨大的。
聯機日志組的交換過程叫做切換,需要特別注意的是,日志切換在一個優化效果不好的數據庫中會引起臨時的“掛起”。掛起大致有兩種情況:
·在歸檔情況下,需要歸檔的日志來不及歸檔,而聯機日志又需要被重新利用
·檢查點事件還沒有完成(日志切換引起檢查點),而聯機日志需要被重新利用
解決這種問題的常用手段是:
i.
增加日志組
ii.
增大日志文件成員大小
通過
v$log
可以查看日志組,
v$logfile
可以查看具體的成員文件。
4
、歸檔日志文件
Oracle
可以運行在兩種模式之中,歸檔模式和不歸檔模式。如果不用歸檔模式,當然,你就不會有歸檔日志,但是,你的系統將不會是一個實用系統,特別是不能用于生產系統,因為你可能會丟失數據。但是在歸檔模式中,為了保存用戶的所有修改,在重做日志文件切換后和被覆蓋之間系統將他們另外保存成一組連續的文件系列,該文件系列就是歸檔日志文件。
有人或許會說,歸檔日志文件占領我大量的硬盤空間,其實,具體想一想,你是愿意浪費一點磁盤空間來保護你的數據,還是愿意丟失你的數據呢?顯而義見,我們需要保證我們的數據的安全性。其實,歸檔并不是一直占領你的磁盤空間,你可以把她備份到磁帶上,或則刪除上一次完整備份前的所有日志文件。
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)
段是對象在數據庫中占用的空間,雖然段和數據庫對象是一一對應的,但段是從數據庫存儲的角度來看的。一個段只能屬于一個表空間,當然一個表空間可以有多個段。
表空間和數據文件是物理存儲上的一對多的關系,表空間和段是邏輯存儲上的一對多的關系,段不直接和數據文件發生關系。一個段可以屬于多個數據文件,關于段可以指定擴展到哪個數據文件上面。
段基本可以分為以下四種
·數據段
(Data Segment)
·索引段
(Index Segment)
·回滾段
(Rollback Segment)
·臨時段
(Temporary Segment)
3
、區間
(Extent)
關于
Extent
的翻譯有多種解釋,有的譯作擴展,有的譯作盤區,我這里通常譯為區間。在一個段中可以存在多個區間,區間是為數據一次性預留的一個較大的存儲空間,直到那個區間被用滿,數據庫會繼續申請一個新的預留存儲空間,即新的區間,一直到段的最大區間數
(Max Extent)
或沒有可用的磁盤空間可以申請。
在
ORACLE8i
以上版本,理論上一個段可以無窮個區間,但是多個區間對
ORACLE
卻是有性能影響的,
ORACLE
建議把數據分布在盡量少的區間上,以減少
ORACLE
的管理與磁頭的移動。
4
、
Oracle
數據塊
(Block)
ORACLE
最基本的存儲單位,他是
OS
數據塊的整數倍。
ORACLE
的操作都是以塊為基本單位,一個區間可以包含多個塊(如果區間大小不是塊大小的整數倍,
ORACLE
實際也擴展到塊的整數倍)。
5
、基本表空間介紹
a.
系統表空間
主要存放數據字典和內部系統表基表
查看數據數據字典的
SQL
select * from dict
查看內部系統表的
SQL
select * from v$fixed_view_definition
DBA
對系統的系統表中的數據字典必須有一個很深刻的了解,他們必須準備一些基礎的
SQL
語句,通過這些
SQL
可以立即了解系統的狀況和數據庫的狀態,這些基本的
SQL
包括
系統的剩余空間
系統的
SGA
狀態系統的等待
用戶的權限
當前的用戶鎖
緩沖區的使用狀況等
在成為
DBA
的道路上我們不建議你過分的依賴于
OEM/Quest
等優秀的數據庫管理工具,因為他們不利于你對數據數據字典的理解,
SQL
語句可以完成幾乎全部的數據庫管理工作。
大量的讀少量的寫是該表空間的一個顯著的特點。
b.
臨時表空間
.
臨時表空間顧名思義是用來存放臨時數據的,例如排序操作的臨時空間,他的空間會在下次系統啟動的時候全部被釋放。
c.
回滾段表空間
i.
回滾段在系統中的作用
當數據庫進行更新插入刪除等操作的時候,新的數據被更新到原來的數據文件,而舊的數據
(Before Image)
就被放到回滾段中,如果數據需要回滾,那么可以從回滾段將數據再復制到數據文件中。來完成數據的回滾。在系統恢復的時候,
回滾段可以用來回滾沒有被
commit
的數據,解決系統的一直性讀。
?????
回滾段在什么情況下都是大量的寫,一般是少量讀,因此建議把回滾段單獨出來放在一個單獨的設備(如單獨的磁盤或
RAID
),以減少磁盤的
IO
爭用。
ii.
回滾段的工作方式
·一個回滾表空間可以被劃分成多個回滾段
.
·一個回滾段可以保存多個會話的數據
.
·回滾段是一個圓形的數據模型
假設回滾段由
4
個區間組成,他們的使用順序就是區間
1
à區間
2
à區間
3
à區間
4
à區間
1
。也就是說,區間是可以循環使用的,當區間
4
到區間
1
的時候,區間
1
里面的會話還沒有結束
,
區間
4
用完后就不能再用區間
1,
這時系統必須分配區間
5
,來繼續為其他會話服務服務。
我們分析一個
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
算法和數據緩沖區
我們知道
Oracle
數據庫的文件大小遠遠大于
Oracle
的所擁有的內存區域
SGA
,
LRU
就是一種盡可能將常用的數據保留在內存的算法。當數據庫需要一個數據緩沖區,他會從數據庫緩沖區的
LRU
隊列的尾部找一個空閑的緩沖,將一個數據塊讀入,然后數據庫會把這個緩沖區放到
LRU
隊列的中部,如果該緩沖被其他程序用到的話,那么他會往隊列的頭上移動,如果這個緩沖沒有被其他程序用到,并且沒有被修改過,那么他會慢慢的移動到
LRU
隊列的尾部,最終被認為是空緩沖區被其他數據塊所覆蓋。一旦這個緩沖區被修改過
DBWR
把他從
LRU
隊列中移出,放到
LRUW
隊列
(
也叫贓緩沖區
)
中,等待
DBWR
把他們批量寫入數據文件,然后再把他們的緩沖區連接到
LRU
隊列的尾部,周而復始的工作。
理解
HASH
算法,為了提高速度
Oracle
在設計中采用了大量的
HASH
算法,這里我們講一下
HASH
算法的理論知識,在以后的閱讀中會對
Oracle
有更好的理解。
HASH
是一種以空間換取時間的做法。假如我有
100
萬條數據,以隊列的方式存儲,如果我要從里面找一條數據,那么我要從頭開始找,我所需要的空間是
100
萬個存儲單元,如果我用
HASH
的方法來存儲,我把存儲空間劃分為
1000*2000
的數組,把
100
萬個數據分別按照如下規則添入該數組:
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
的區別,其實很簡單,
Latch
是
Oracle
內部的
Lock
,他負責更為細小的內部讀寫,比如
Oracle
要把用戶更新的數據寫入緩沖區,這時候
Oracle
就會在該緩沖區上加上
latch
,用來防止
DBWR
把他寫出到磁盤,因為如果沒有這個
Latch
,
DBWR
會把一半新一半老沒有用的數據寫到磁盤上。
?
?
五、常見問題
1
、實例和
SID
的關系是什么?
經常有人問
SID
是什么?在
Oracle
系統中
SID
是一個經常出現的變量,如環境變量
ORACLE_SID
,
初始化文件
initSID.ora
,那究竟什么是
SID
呢?其實
SID
就是
Oracle
實例的標識,不同的
SID
對應不同的內存緩沖
(SGA)
和不同的后臺進程。這樣一來我們就可以得當在一臺物理的服務器上可以有多個
SID
的數據庫實例。
2
、
Oracle
數據庫和實例的關系是什么?
數據庫是由物理文件和存取數據文件的實例組成,當存取數據文件的實例是一個的時候,數據庫被稱做單節點數據庫。這是我們看到的最多的數據庫形式。當然還有一種多節點數據庫,就是一個以上的實例共同訪問一個數據庫
(
或者說共同訪問一組數據文件
)
,
更好的提供穩定性和并行處理能力。這在
8i
中被稱為
OPS(Oracle Parallel Server )
,在
Oracle9i
中被稱為
RAC(real application cluster)
。在這種數據庫中。兩個
/
多個實例分別在不同服務器上,所有
Oracle
數據文件在共享的磁盤陣列上,多個服務器上的實例可以同時工作,他們通過一個內部的網絡進行通信。如果一臺服務器不能提供服務的話,另一臺會接管它的工作,特別是在關鍵的業務有很大的潛力。
3
、在運行的數據庫中數據文件中是不是可能存在沒有被提交的數據?
這是可能存在的,因為用戶數據文件的數據是由
DBWR
寫入的,
DBWR
是一個很底層的后臺進程,不負責與用戶交互。用戶的交互是由
LGWR
完成的。
4
、在問題
3
中,如果存在沒有寫入的數據,那么機器突然斷電,數據完整性會不會損壞?
不會的,因為數據庫的完整性是
LGWR
來保證的,而且
ORACLE
保證了
DBWR
寫入數據文件的任何修改已經被記錄在重做日志文件中。當系統再次啟動的時候,通過讀取重做日志文件就可以知道那些數據沒有被提交。這時候
ORACLE
會自動回滾那些數據。所以說聯機日志的損壞,特別是當前聯機日志的損壞,對數據庫的影響是巨大的,可能會導致數據庫的不完整。
5
、數據文件損壞會丟失數據嗎?
可以這么說,如果你有備份和歸檔,就不會。因為所有對數據修改的記錄都在重做日志中有記錄,所以不會丟失數據,你只要恢復以前的備份再用歸檔日志文件恢復和當前的在線重做日志就可以恢復所有數據。
6
、在線重做日志損壞會丟失數據嗎?
以上說了,在線日志對數據庫的損壞是極大的,所以不僅可能丟失數據,還可能引起數據庫的不同步。在重做日志中的所有
commit
的記錄都會丟失,這也是
Oracle
為什么要對在線重做日志文件做鏡像的原因。任何的數據丟失都是不允許的。
7
、我在事務能不能指定不寫回滾段?
不可以的,寫回滾段是
ORACLE
保證一致性讀和事務一致性的根本?;貪L段是高寫入段,建議把它放到單獨的設備上來。
對于
DDL
語句,如
DROP,TRUNCATE
卻可以不寫回滾段(沒有
UNDO
信息),所以對于整個表的刪除,如果數據量比較大,建議用
Truncate Table
的方法。
不寫聯機日志也是不可能的,但可以在某些特定操作中,可以寫很少的聯機日志,如以
NOLOGGING
的方式通過
Create table tablename as select
創建表,或以
Append
的方式
Insert
數據到表,或直接載入等操作。
六、小結
這里,我們了解了實例和數據庫的關系,一個數據庫可以有多個實例,但是一個實例卻不可能對應多個數據庫,在一般的情況下,我們都是用的單節點數據庫,即一個實例僅僅對應一個數據庫。
我們了解了
ORACLE
實例的組成,包括內存和后臺進程,進一步解釋了
SGA
的組成與
SGA
的作用,并分析了語句重用的好處。在后臺進程中,重要的闡述了
DBWR
與
LGWR
,其中
DBWR
是一個底層的由
ORACLE
控制的后臺進程,而
LGWR
負責與用戶交互
.
在
ORACLE
數據庫中
,
我們重要闡述了數據庫的物理與邏輯結構,在物理結構中,需要注意四類以下文件:控制文件,聯機日志,數據文件與參數文件。在邏輯結構中,需要清楚每個邏輯結構的關系,從大到小的順序為:表空間à段à區間à塊。
最后,簡單的描敘了兩個
ORACLE
的核心內容,
LRU
算法與
LATCH
,并初步闡述了
HASH
算法的相關內容。有關
ORACLE
更多的核心內容,可以參考相關資料。
?
?
參考文獻:
http://www.happyit.net
ORACLE
聯機文檔
Expert One-on-one Oracle? [
美
] Thomas Kyte
著
清華大學出版社
Oracle 8i Web
開發指南
[
美
] Dan Hotka,et al.
著
清華大學出版社
Oracle 8i DBA Architecture & Administration and backup & Recovery Study Guide
?[
美
] Dong Stuns Biju Thomas
著
電子工業出版社
Oracle
數據庫管理員技術指南
[
美
] Sumit Sarin
著
機械工業出版社
?