ORACLE 體系結構

ORACLE 體系結構

(Architecture of ORACLE)

?

第一部分:ORACLE8i體系結構

第一章. 概要

在本章裏你可以瞭解以下內容

1 理解ORACLE 實例的組成

2 理解ORACLE 數據庫的組成

3 理解ORACLE內存結構的組成

4 理解後臺進程的作用與分工

5 理解數據庫的物理文件與對應的邏輯結構

6 理解ORACLE的整體構架

第二章. 理解ORACLE實例

2.1 ORACLE SERVER

ORACLE是一個可移植的數據庫——它在相關的每一個平臺上都可以使用,即所謂的跨平臺特性。在不同的操作系統上也略有差別,如在UNIX/LINUX上,ORACLE是多個進程實現的,每一個主要函數都是一個進程;而在Windows上,則是一個單一進程,但是在該進程中包含多個線程。但是從整體構架上來看,ORACLE在不同的平臺上是一樣的,如內存結構、後臺進程、數據的存儲。

一個運行着的ORACLE數據庫就可以看成是一個ORACLE SERVER,該SERVER數據庫(Database)和實例(Instance)組成,在一般的情況下一個ORACLE SERVER包含一個實例和一個與之對應的數據庫,但是在特殊情況下,如8iOPS9iRAC,一個SERVER中一個數據庫可以對應多個實例。

一系列物理文件(數據文件,控制文件,聯機日誌等)的集合或與之對應的邏輯結構(表空間,段等)被稱爲數據庫,簡單的說,就是一系列與磁盤有關係的物理文件的組成。ORACLE內存結構和後臺進程被成爲數據庫的實例,一個實例最多隻能安裝(Mount)和打開(Open)在一個數據庫上,負責數據庫的相應操作並與用戶交互。

實例與數據庫的關係如下圖所示:

圖一 ORACLE SERVER

2.2 ORACLE內存結構 (Memory structure)

2.2.1 內存結構的組成

Oracle內存結構主要可以分共享內存區與非共享內存區,共享內存區主要包含系統全局區SGA(System Global Area),非共享內存區主要由程序全局區PGA(Program Global Area)組成,可以用如下圖形表示。

圖二 ORACLE MEMOERY STRUCTRUE

2.2.2全局共享區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$sgastatV$buffer_pool

主要包括以下幾個部分:

2.2.2.1共享池(Shared pool)

共享池是SGA最關鍵的內存片段,特別是在性能和可伸縮性上。一個太小的共享池會扼殺性能,使系統停止,太大的共享池也會有同樣的效果,將會消耗大量的CPU來管理這個共享池。不正確的使用共享池只會帶來災難。共享池主要又可以分爲以下兩個部分

1SQL語句緩衝(Library Cache)

當一個用戶提交一個SQL語句,Oracle會將這句SQL進行分析(parse),這個過程類似於編譯,會耗費相對較多的時間。在分析完這個SQLOracle會把他的分析結果給保存在Shared poolLibrary Cache中,當數據庫第二次執行該SQL時,Oracle自動跳過這個分析過程,從而減少了系統運行的時間。這也是爲什麼第一次運行的SQL 比第二次運行的SQL要慢一點的原因。

下面舉例說明parse的時間

SQL>Startup

SQL> select count(*) from usertable;

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 usertable;

COUNT(*)

-----------------

243

Elapsed: 00:00:00.02

SQL> select count(*) from usertable;

COUNT(*)

----------------

243

Elapsed: 00:00:00.00

從兩句SQL 的時間差上可以看出該SQL Parse 時間約爲00:00:00.02

對於保存在共享池中的SQL語句,可以從V$Sqltextv$Sqlarea中查詢到,對於編程者來說,要儘量提高語句的重用率,減少語句的分析時間。一個設計的差的應用程序可以毀掉整個數據庫的Share pool,提高SQL語句的重用率必須先養成良好的變成習慣,儘量使用Bind變量。

2、數據字典緩衝區(Data Dictionary Cache)

顯而易見,數據字典緩衝區是ORACLE特地爲數據字典準備的一塊緩衝池,供ORACLE內部使用,沒有什麼可以說的。

2.2.2.2塊緩衝區高速緩存(Database Buffer Cache)----數據塊緩衝區

這些緩衝是對應所有數據文件中的一些被使用到的數據塊。讓他們能夠在內存中進行操作。在這個級別裏沒有系統文件,,戶數據文件,臨時數據文件,回滾段文件之分。也就是任何文件的數據塊都有可能被緩衝。數據庫的任何修改都在該緩衝裏完成,並由DBWR進程將修改後的數據寫入磁盤。

這個緩衝區的塊基本上在兩個不同的列表中管理。一個是塊的“髒”表(Dirty List),需要用數據庫塊的書寫器(DBWR)---數據庫寫入進程來寫入,另外一個是不髒的塊的列表(LRU List),一般的情況下,是使用最近最少使用(Least Recently Used,LRU)算法來管理。

塊緩衝區高速緩存又可以細分爲以下三個部分(Default pool,Keep pool,Recycle pool)。如果不是人爲設置初始化參數(Init.ora)ORACLE將默認爲Default pool

由於操作系統尋址能力的限制,不通過特殊設置,在32位的系統上,塊緩衝區高速緩存最大可以達到1.7G,在64位系統上,塊緩衝區高速緩存最大可以達到10G

2.2.2.3重做日誌緩衝區(Redo log buffer)

重做日誌文件的緩衝區,對數據庫的任何修改都按順序被記錄在該緩衝,然後由LGWR進程將它寫入磁盤。這些修改信息可能是DML語句,如(Insert,Update,Delete),或DDL語句,如(Create,Alter,Drop)

重做日誌緩衝區的存在是因爲內存到內存的操作比較內存到硬盤的速度快很多,所以重作日誌緩衝區可以加快數據庫的操作速度,但是考慮的數據庫的一致性與可恢復性,數據在重做日誌緩衝區中的滯留時間不會很長。所以重作日誌緩衝區一般都很小,大於3M之後的重作日誌緩衝區已經沒有太大的實際意義。

2.2.2.4 Java程序緩衝區(Java Pool)------Java

Java 的程序區,Oracle 8I 以後,Oracle 在內核中加入了對Java的支持。該程序緩衝區就是爲Java 程序保留的。爲Java提供語法分析區。如果不用Java程序沒有必要改變該緩衝區的默認大小。他的大小在init.ora文件的JAVA_POOL_SIZE來設置,默認10M

2.2.2.5大池(Large Pool)

大池的得名不是因爲大,而是因爲它用來分配大塊的內存,處理比共享池更大的內存,在8.0開始引入。

下面對象使用大池:

1、? MTS——在SGALarge Pool中分配UGA

2、? 語句的並行查詢(Parallel Executeion of Statements)——允許進程間消息緩衝區的分配,用來協調並行查詢服務器

3、? 備份(Backup)——用於RMAN磁盤I/O緩存

2.2.3程序共享區 Program Global Area(PGA)

Program Global Area(PGA)是用來保存與用戶進程相關的內存段,PGA總是由進程或線程在本地分配,其它進程與線程無法訪問。--------所以非共享J

User Global Area(UGA)實際上是會話的狀態,它是會話必須始終能夠得到的內存。對於專用服務器進程,UGAPGA中分配。對於多線程進程,UGALarge pool中分配。

PGA/UGA一般保存了用戶的變量、權限、堆棧、排序(Sort)空間等信息。影響PGA/UGA最大的也就是Sort信息,由初始化參數sort_area_size決定,由於Sort信息分配在UGA中,所以在共享服務器中能更好的利用內存。

2.3 後臺進程 (Background process)

後臺進程是Oracle的程序,用來管理數據庫的讀寫,恢復和監視等工作。Server Process主要是通過他和user process進行聯繫和溝通,並由他和user process進行數據的交換。Unix機器上,Oracle後臺進程相對於操作系統進程,也就是說,一個Oracle後臺進程將啓動一個操作系統進程;在Windows機器上,Oracle後臺進程相對於操作系統線程,打開任務管理器,我們只能看到一個ORACLE.EXE的進程,但是通過另外的工具,就可以看到包含在這裏進程中的線程。後臺進程與其它結構的關係如圖所示:

圖三ORACLE BACKGROUP PROCESS

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

Oracle系統有5 個基本進程他們是

DBWR(數據文件寫入進程)

LGWR(日誌文件寫入進程)

SMON(系統監護進程)

PMON(用戶進程監護進程)

CKPT(檢查點進程,同步數據文件, 日誌文件,控制文件)

2.3.1 數據寫進程DBWR

將修改過的數據緩衝區的數據寫入對應數據文件

維護系統內的空緩衝區

這裏指出幾個容易錯誤的概念:

·當一個更新提交後,DBWR把數據寫到磁盤並返回給用戶提交完成。

·DBWR會觸發CKPT 後臺進程

·DBWR不會觸發LGWR 進程

上面的概念都是錯誤的。

DBWR是一個很底層的工作進程,他批量的把緩衝區的數據寫入磁盤。和任何前臺用戶的進程幾乎沒有什麼關係,也不受他們的控制。至於DBWR會不會觸發LGWRCKPT進程,我們將在下面幾節裏討論。//也就是說,DBWR進程不會在一個更新提交後把數據寫到磁盤,他會批量的自己決定什麼時候把緩衝區的數據寫入磁盤J

DBWR工作的主要條件如下

·DBWR 超時

·系統中沒有多的空緩衝區用來存放數據

·CKPT 進程觸發DBWR

2.3.2日誌寫進程LGWR

將重做日誌緩衝區的數據寫入重做日誌文件,LGWR是一個必須和前臺用戶進程通信的進程。當數據被修改的時候,系統會產生一個重做日誌並記錄在重做日誌緩衝區內。這個重做日誌可以類似的認爲是以下的一個結構:

SCN=000000001000

數據塊ID

對象ID=0801

數據行=02

修改後的數據=0011

提交的時候,LGWR必須將被修改的數據的重做日誌緩衝區內數據寫入日誌數據文件,然後再通知前臺進程提交成功,並由前臺進程通知用戶。從這點可以看出LGWR承擔了維護系統數據完整性的任務。

LGWR 工作的主要條件如下

·用戶提交

·有1/3 重做日誌緩衝區未被寫入磁盤

·有大於1M 重做日誌緩衝區未被寫入磁盤

·超時

·DBWR需要寫入的數據的SCN號大於LGWR 記錄的SCN號,DBWR 觸發LGWR寫入

2.3.3系統監控SMON

工作主要包含

·清除臨時空間

·在系統啓動時,完成系統實例恢復

·聚結空閒空間

·從不可用的文件中恢復事務的活動

·OPS中失敗節點的實例恢復

·清除OBJ$

·縮減回滾段

·使回滾段脫機

2.3.4進程監控PMON

主要用於清除失效的用戶進程,釋放用戶進程所用的資源。如PMON將回滾未提交的工作,釋放鎖,釋放分配給失敗進程的SGA資源。

2.3.5檢查點進程CKPT

同步數據文件,日誌文件和控制文件,由於DBWR/LGWR的工作原理,造成了數據文件,日誌文件,控制文件的不一至,這就需要CKPT進程來同步。CKPT會更新數據文件/控制文件的頭信息。

CKPT工作的主要條件如下

·在日誌切換的時候

·數據庫用immediate ,transaction , normal 選項shutdown 數據庫的時候

·根據初始話文件LOG_CHECKPOINT_INTERVALLOG_CHECKPOINT_TIMEOUTFAST_START_IO_TARGET 的設置的數值來確定

·用戶觸發

以下進程的啓動需要手工配置

2.3.6歸檔進程ARCH

當數據庫以歸檔方式運行的時候,Oracle會啓動ARCH進程,當重做日誌文件被寫滿時,日誌文件進行切換,舊的重做日誌文件就被ARCH進程複製到一個/多個特定的目錄/遠程機器。這些被複制的重做日誌文件被叫做歸檔日誌文件。

2.3.7分佈式恢復RECO

負責解決分佈事物中的故障。Oracle可以連接遠程的多個數據庫,當由於網絡問題,有些事物處於懸而未決的狀態。RECO進程試圖建立與遠程服務器的通信,當故障消除後,RECO進程自動解決所有懸而未決的會話。

2.3.8服務進程Server Process

服務進程的分類

·專用服務進程(Dedicated Server Process)

一個服務進程對應一個用戶進程

·共享服務進程(MultiTreaded Server Process)

一個服務進程對應多個用戶進程,輪流爲用戶進程服務。

2.3.9用戶進程User Process

在客戶端,負責將用戶的SQL 語句傳遞給服務進程,並從服務器段拿回查詢數據。

2.4 一個貫穿數據庫全局的概念----系統改變號SCN(System Change Number)

系統改變號,一個由系統內部維護的序列號。當系統需要更新的時候自動增加,他是系統中維持數據的一致性和順序恢復的重要標誌。

運行以下語句可以得到系統SCN

SQL> select max(ktuxescnw * power(2, 32) + ktuxescnb) scn from x$ktuxe;

?? SCN

----------

? 31014

SCN有如下特點:

a. 查詢語句不會使SCN增加,就算是同時發生的更新,數據庫內部對應的SCN也是不同的。這樣一來就保證了數據恢復時候的順序。

b. 維持數據的一致性,當一個查詢執行的時候,他會先從系統中得到一個當前的SCN號,在他查找數據的同時,他會檢查每個數據行和他對應的SCN號,只有那些不比他的SCN號大的行才能從對應用戶數據文件的緩衝區內取出,而那些大於他SCN號的行,就應該從回滾段數據文件的緩衝中取出。

實例分析:

一個查詢返回以下5

ID Name

-------------------------------------

1 ShangHai

2 Beijing

3 Gugangzhou

4 ShenZhen

5 HanZhou

用戶A12:00開始運行,到12:05結束在12:01用戶B執行了一條Update語句,更新了ID2的那條記錄把Beijing該成了Tianjing.並提交,這時候用戶A 的那個查詢是不會出現Tianjing的記錄。12:00查詢時候的SCNN然後用戶B的更新使得系統的SCN變成N+1當用戶A查詢到ID=2的記錄的時候發現他的SCN已經大於查詢開始時候的SCN,他就會在回滾段數據緩衝中找到SCN=N的那條記錄,並把它返回。

第三章. ORACLE 數據庫(Database

3.1物理結構——物理操作系統文件的集合.

3.1.1 控制文件 Control files

參數文件init.ora記錄了控制文件的位置,控制文件是一個非常小的二進制文件,最大可以增長到64MB,控制文件包括如下主要信息

·數據庫的名字,檢查點信息,數據庫創建的時間戳

·所有的數據文件,聯機日誌文件,歸檔日誌文件信息

·備份信息等

有了這些信息,Oracle就知道那些文件是數據文件,現在的重做日誌文件是哪些,這些都是系統啓動和運行的基本條件,所以他是Oracle運行的根本。如果沒有控制文件系統是不可能啓動的。控制文件是非常重要的,一般採用多個鏡相複製來保護控制文件,或採用RAID來保護控制文件。控制文件的丟失,將使數據庫的恢復變的很複雜。

控制文件信息可以從V$Controlfile中查詢獲得

3.1.2數據文件(Data files

數據文件的詳細信息記載在控制文件中

可以通過如下方式查看數據文件

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

數據文件是ORACLE中最重要的物理文件,直接記錄了用戶數據。按照使用上的不同,可以把數據文件分成如下幾類:

·系統數據文件

·回滾數據文件

·臨時數據文件

·用戶數據文件

以上各類文件分別屬於不同性質的表空間,在以下的邏輯結構中,將進一步說明該類型文件的作用。

3.1.3重做日誌文件(Redo files

用戶對數據庫進行的任何操作都會記錄在重做日誌文件。在瞭解重做日誌之前必須瞭解重做日誌的兩個概念,重做日誌組重做日誌組成員(Member),一個數據庫中至少要有兩個日誌組文件,一組寫完後再寫另一組,即輪流寫。每個日誌組中至少有一個日誌成員,一個日誌組中的多個日誌成員是鏡相關係,有利於日誌文件的保護,因爲日誌文件的損壞,特別是當前聯機日誌的損壞,對數據庫的影響是巨大的。

聯機日誌組的交換過程叫做切換,需要特別注意的是,日誌切換在一個優化效果不好的數據庫中會引起臨時的“掛起”。掛起大致有兩種情況:

·在歸檔情況下,需要歸檔的日誌來不及歸檔,而聯機日誌又需要被重新利用

·檢查點事件還沒有完成(日誌切換引起檢查點),而聯機日誌需要被重新利用

解決這種問題的常用手段是:

i.增加日誌組

ii.增大日誌文件成員大小

一個包含三個日誌組,每個日誌組兩個成員的聯機日誌組成與運行大致如圖所示:

圖四 REDO LOG

通過v$log可以查看日誌組,v$logfile可以查看具體的成員文件。

3.1.4歸檔日誌文件(Archived files

Oracle可以運行在兩種模式之中,歸檔模式和不歸檔模式。如果不用歸檔模式,當然,你就不會有歸檔日誌,但是,你的系統將不會是一個實用系統,特別是不能用於生產系統,因爲你可能會丟失數據。但是在歸檔模式中,爲了保存用戶的所有修改,在重做日誌文件切換後和被覆蓋之間系統將他們另外保存成一組連續的文件系列,該文件系列就是歸檔日誌文件。

有人或許會說,歸檔日誌文件佔領我大量的硬盤空間,其實,具體想一想,你是願意浪費一點磁盤空間來保護你的數據,還是願意丟失你的數據呢?顯而義見,我們需要保證我們的數據的安全性。其實,歸檔並不是一直佔領你的磁盤空間,你可以把她備份到磁帶上,或則刪除上一次完整備份前的所有日誌文件。

通過v$archived_logv$log_history可以查看歸檔日誌文件的信息。

3.1.5初始化參數文件(Parameter file

initSID.orainit.ora文件,因爲版本的不一樣,其位置也可能會不一樣。在8i中,通常位於$ORACLE_HOME/admin//Pfile下。在9i以下參數文件是一個純文本文件,可以用文本編輯器打開修改,從9i開始,多了一個叫spfile的參數文件,以二進制方式保存。

初始化文件記載了許多數據庫的啓動參數,如內存,控制文件,進程數等,在數據庫啓動的時候加載(Nomount時加載),初始化文件記錄了很多重要參數,對數據庫的性能影響很大,如果沒有它,數據庫將無法啓動。在9i以前,對參數文件的修改,必須重新啓動數據庫才能使參數生效,從9i開始,可以用命令來修改spfile文件的內容了。

參數文件中的參數不是一直一成不變的,隨着版本的不同而不同。大多數參數,如Db_block_size的壽命就很長,其它很多參數隨着版本的改變就被廢棄了。除了文檔記錄的參數外,ORACLE還支持很多內部參數,當然,這些參數是不建議被使用的。

通過v$parameter視圖可以查詢當前的參數設置。

3.1.6其他文件

i . 密碼文件

用於Oracle 的具有sysdba權限用戶的認證,在9i以前主要指Internal用戶,從9i開始已經取消了這個用戶。密碼文件的密碼可以通過ORAPWD命令來修改。

ii. 日誌文件

·報警日誌文件(alert.logalrt.ora

記錄數據庫啓動,關閉和一些重要的出錯信息。數據庫管理員應該經常檢查這個文件,並對出現的問題作出即使的反應。你可以通過以下SQL 找到他的路徑select value from v$parameter where name ='background_dump_dest',或通過參數文件獲得其路徑。

·後臺跟蹤文件

路徑與報警文件路徑一致,記載了系統後臺進程出錯時寫入的信息。

·用戶跟蹤文件

記載了用戶進程出錯時寫入的信息,一般不可能讀懂,可以通過ORACLETKPROF工具轉化爲可以讀懂的格式。用戶跟蹤文件的路徑,你可以通過以下SQL找到他的路徑select value from v$parameter where name ='user_dump_dest',或通過參數文件獲得其路徑。

可以通過設置用戶跟蹤或dump命令來產生用戶跟蹤文件,一般在調試、優化、系統分析中有很大的作用。

第四章. ORACLE邏輯結構(Logical structure

ORACLE邏輯結構由一系列有相互關係的邏輯對象組成。如圖:

圖五LOGICAL STRUCTURE

4.1表空間(tablespace)

表空間是數據庫中的基本邏輯結構,一系列數據文件的集合。一個表空間可以包含多個數據文件,但是一個數據文件只能屬於一個表空間

8i以前,表空間的管理類型只有一種,被稱爲字典管理表空間(DMT),即在數據字典中管理表空間中的空間的分配。在8i以後的版本,爲了減少在字典上的開銷,引入了本地管理的表空間(LMT),在該類型的表空間中,在每個數據文件中存儲的位圖來管理空間的分配,不再要求使用數據字典。本地管理的表空間有速度快,無碎片等衆多優點,建議用戶表空間都實現本地管理。

通過v$tablespace可以查詢表空間,DBA_TABLESPACE可以查詢詳細表空間信息。

4.2 (Segment)

段是對象在數據庫中佔用的空間,雖然段和數據庫對象是一一對應的,但段是從數據庫存儲的角度來看的。一個段只能屬於一個表空間,當然一個表空間可以有多個段。

表空間和數據文件是物理存儲上的一對多的關係,表空間和段是邏輯存儲上的一對多的關係,段不直接和數據文件發生關係。一個段可以屬於多個數據文件,關於段可以指定擴展到哪個數據文件上面。

段基本可以分爲以下四種

·數據段(Data Segment)

·索引段(Index Segment)

·回滾段(Rollback Segment)

·臨時段(Temporary Segment)

通過DBA/ALL/USER_SEGMENTS可以查詢詳細的段信息。

4.3區間(Extent)--------還是叫“擴展段”比較好

關於Extent的翻譯有多種解釋,有的譯作擴展,有的譯作盤區,我這裏通常譯爲區間。在一個段中可以存在多個區間,區間是爲數據一次性預留的一個較大的存儲空間,直到那個區間被用滿,數據庫會繼續申請一個新的預留存儲空間,即新的區間,一直到段的最大區間數(Max Extent)或沒有可用的磁盤空間可以申請。

ORACLE8i以上版本,理論上一個段可以無窮個區間,但是多個區間對ORACLE卻是有性能影響的,ORACLE建議把數據分佈在儘量少的區間上,以減少ORACLE的管理與磁頭的移動,但是在某些特殊情況下,需要把一個段分佈在多個數據文件或多個設備上,適當的加多區間數也是有很大好處的。

通過DBA/ALL/USER_EXTENTS可以查詢詳細的區間信息。

4.4 Oracle數據塊(Block)

ORACLE最基本的存儲單位,在建立數據庫的時候指定,雖然在初始化文件中可見,但是不能修改。爲了保證存取的速度,它是OS數據塊的整數倍ORACLE的操作都是以塊爲基本單位,一個區間可以包含多個塊,如果區間大小不是塊大小的整數倍,ORACLE實際也擴展到塊的整數倍。

塊的內部結構與數據的存取方法都是比較複雜的,以表段的塊爲例,從簡單的結構上劃分,可以把塊的內部劃分成如下幾個部分:公用頭,表目錄,行目錄,可存取空間等。

以下是一個表塊的大致結構圖:

圖六 TABLE BLOCK

塊頭(BLOCK HEADER)包含着關於塊類型(表塊、索引塊等等)的信息、關於塊上活動和過時事務信息、磁盤上筷的地址的信息。表目錄(Table directory),如果給出的話,包含着此塊中存儲各行的表的信息(多個表的數據可能保存在同一個塊中)。行目錄(Row directory)包含在塊中發現的描述行的信息。以上3部分爲塊的開銷(Block Overhead),其餘部分爲可用存儲空間,可以用如下查詢獲得可用空間大小。

Select kvisval,kvistag,kvisdsc from sys.x$kvis;

一般的8K(8192)的塊可用空間爲8168

PCTFREEPCTUSED是表的兩個存取參數,其實是作用在表中的塊上面的,PCTFREEPCTUSED表示兩個百分比,默認分別是1040PCTFREE表示保留該百分比的可用空間用於以後的行更新,避免行遷移。如果行數據達到PCTFREE保留的空間,該塊從FREE LIST上撤消下來,不再接收數據。PCTUSED表示當行的空閒空間降低(如刪除數據)到該參數指定的百分比的時候,該塊重新進入FREE LIST,開始接收新的數據。PCTFREEPCTUSED的配置與系統的優化有一定的關係,所以要慎重,PCTFREE+PCTUSED不要大於等於100,否則將導致塊不斷的在FREELIST移上移下,嚴重影響性能。

4.5基本表空間介紹

4.5.1系統表空間(System)

該表空間包含的數據文件稱爲系統數據文件。

該表空間存放系統表和數據字典,一般不放用戶的數據,但是用戶腳本,如過程,函數,包等卻是保存在數據字典中的。

數據字典是一些系統表或視圖,他存放系統的信息,他包括數據庫版本,數據文件信息,表與索引等段信息,系統的運行狀態等各種和系統有關的信息和用戶腳本信息。數據庫管理員可以通過對數據字典的查詢,就可以瞭解到Oracle的運行狀態。

查看數據數據字典的SQL

select * from dict

查看內部系統表的SQL

select * from v$fixed_view_definition

DBA對系統的系統表中的數據字典必須有一個很深刻的瞭解,他們必須準備一些基礎的SQL語句,通過這些SQL可以立即瞭解系統的狀況和數據庫的狀態,這些基本的SQL包括

·系統的剩餘空間

·系統的SGA

·狀態系統的等待

·用戶的權限

·當前的用戶鎖

·緩衝區的使用狀況等

在成爲DBA 的道路上我們不建議你過分的依賴於OEM/Quest 等優秀的數據庫管理工具,因爲他們不利於你對數據數據字典的理解,SQL語句可以完成幾乎全部的數據庫管理工作。

大量的讀少量的寫是該表空間的一個顯著的特點。

4.5.2 臨時表空間(Temporary)

該表空間包含的數據文件稱爲臨時數據文件

主要存放用戶的排序等臨時數據,因爲沒有辦法在一個永久表空間上開闢臨時段,所以就必須有一個臨時表空間,主要用於不能在內存上進行的排序操作。我們必須爲用戶指定一個臨時表空間。

臨時段佔有的空間會在下次系統啓動的時候全部被釋放。

4.5.3 回滾段表空間(Rollback)

如果數據庫進行對數據的修改,那麼就必須使用回滾段,回滾段是用來臨時存放修改前的數據(UNDO)回滾段通常都放在一個單獨的表空間上(回滾表空間),避免表空間碎片化,這個表空間包含的數據文件就是回滾數據文件。

4.5.3.1回滾段在系統中的作用

當數據庫進行更新插入刪除等操作的時候,新的數據被更新到原來的數據文件,而舊的數據(Before Image)就被放到回滾段中,如果數據需要回滾,那麼可以從回滾段將數據再複製到數據文件中。來完成數據的回滾。在系統恢復的時候, 回滾段可以用來回滾沒有被commit 的數據,解決系統的一直性讀。

回滾段在一般情況下都是大量的寫,少量讀,因此建議把回滾段單獨出來放在一個單獨的設備(如單獨的磁盤或RAID),以減少磁盤的IO爭用。

4.5.3.2回滾段的工作方式

·一個回滾表空間可以被劃分成多個回滾段.

·一個回滾段可以保存多個會話的數據.

·回滾段是一個圓形的數據模型

假設回滾段由4 個區間組成,他們的使用順序就是區間1à區間2à區間3à區間4à區間1。也就是說,區間是可以循環使用的,當區間4到區間1的時候,區間1裏面的會話還沒有結束, 區間4用完後就不能再用區間1,這時系統必須分配區間5,來繼續爲其他會話服務服務。這也就是爲什麼回滾段在大事務的情況下會不斷“漲大”的原因,回滾段的擴充是影響性能的,要儘量避免。

這是一個回滾段從4個區間簡單的擴充到5個區間的例子:

圖七 ROLLBACK SEGMENT

我們分析一個Update 語句的完成

1、用戶提交一個Update 語句

2Server Process 檢查內存緩衝.

如果沒有該數據塊的緩衝,則從磁盤讀入

i. 如果沒有內存的有效空間,DBWR被啓動將未寫入磁盤的髒緩衝寫入磁盤

ii. 如果有有效空間,則讀入

3、在緩衝內更新數據

i. 申請一個回滾段入口,將舊數據寫如回滾段

ii. 加鎖並更新數據

iii. 並在同時將修改記錄在Redo log buffer

4、用戶提交一個Commit 語句

i. SCN增加

ii. Redo log buffer 寫入Redo log file

iii. 返回用戶Commit 完成

4.5.4用戶表空間(User)

其包含的數據文件稱爲用戶數據文件

一般是由用戶建立,來存取用戶數據的表空間,一般有兩類常見的用戶型數據,數據和索引,一般來說,如果條件許可的話,可以考慮放在不同的磁盤上。

第五章. 常見問題

1、實例和SID的關係是什麼?

經常有人問SID 是什麼?在Oracle 系統中SID 是一個經常出現的變量,如環境變量ORACLE_SID 初始化文件initSID.ora,那究竟什麼是SID 呢?其實SID 就是Oracle 實例的標識,不同的SID 對應不同的內存緩衝(SGA)和不同的後臺進程。這樣一來我們就可以得當在一臺物理的服務器上可以有多個SID 的數據庫實例。

2Oracle數據庫和實例的關係是什麼?

數據庫是由物理文件和存取數據文件的實例組成,當存取數據文件的實例是一個的時候,數據庫被稱做單節點數據庫。這是我們看到的最多的數據庫形式。當然還有一種多節點數據庫,就是一個以上的實例共同訪問一個數據庫(或者說共同訪問一組數據文件) 更好的提供穩定性和並行處理能力。這在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保證一致性讀和事務一致性的根本。回滾段是高寫入段,建議把它放到單獨的設備上來。

對於DDL語句,如DROP,TRUNCATE卻可以不寫回滾段(沒有UNDO信息),所以對於整個表的刪除,如果數據量比較大,建議用Truncate Table的方法。也就是說,DROP一個表後不可能通過rollback恢復!!J

不寫聯機日誌也是不可能的,但可以在某些特定操作中,可以寫很少的聯機日誌,如以NOLOGGING的方式通過Create table tablename as select創建表,或以Append的方式Insert數據到表,或直接載入等操作。

第六章. 小結

這裏,我們瞭解了實例和數據庫的關係,一個數據庫可以有多個實例,但是一個實例卻不可能對應多個數據庫,在一般的情況下,我們都是用的單節點數據庫,即一個實例僅僅對應一個數據庫。

我們瞭解了ORACLE實例的組成,包括內存和後臺進程,進一步解釋了SGA的組成與SGA的作用,並分析了語句重用的好處。在後臺進程中,重要的闡述了DBWRLGWR,其中DBWR是一個底層的由ORACLE控制的後臺進程,而LGWR負責與用戶交互.

ORACLE數據庫中,我們重要闡述了數據庫的物理與邏輯結構,在物理結構中,需要注意四類以下文件:控制文件,聯機日誌,數據文件與參數文件。在邏輯結構中,需要清楚每個邏輯結構的關係,從大到小的順序爲:表空間àà區間à塊。

?

?

?

?

?

?

第二部分:ORACLE9i新特性

一、創建數據庫

9i創建數據庫的工具改名爲DBCA,也可以通過腳本更輕鬆容易的創建數據庫,如:

create database ${ORACLE_SID}

user sys identified by sys

user system identified by system

logfile group 1 ('${ORACLE_BASE}/oradata/${ORACLE_SID}/redo01.log') size 10M,

group 2 ('${ORACLE_BASE}/oradata/${ORACLE_SID}/redo02.log') size 10M,

group 3 ('${ORACLE_BASE}/oradata/${ORACLE_SID}/redo03.log') size 10M

maxlogfiles 5

maxlogmembers 5

maxloghistory 1

maxdatafiles 254

maxinstances 1

archivelog

character set ZHS16GBK

national character set AL16UTF16

datafile '${ORACLE_BASE}/oradata/${ORACLE_SID}/system01.dbf' size 300M

default temporary tablespace tbstemp tempfile

??'${ORACLE_BASE}/oradata/${ORACLE_SID}/temp01.dbf' size 500M

undo tablespace tbsundo datafile

'${ORACLE_BASE}/oradata/${ORACLE_SID}/undo01.dbf' size 500M;

其特點爲使用專用的回滾和臨時表空間,而不象Oracle 8i中的那樣,回滾和臨時表空間與普通表空間沒有差異,這樣既簡化了配置也有利於效能提高。要注意臨時表空間的指定文件關鍵字是tempfile而不是通用的datafile,而且臨時表空間的存儲選項由Oracle系統決定。同樣回滾表空間也是由Oracle系統決定,不必人工干預。

二、二進制的參數文件

Oracle 9i$ORACLE_HOME/dbs下可使用二進制配置文件,缺省爲spfile{SID}.ora,如spfileoradb.ora,支持Oracle系統進程在不重啓的情況下動態調整參數,這對要求不間斷運行的系統是有利的。在建庫階段就可將此配置文件創建起來。

create spfile from pfile;

or

create spfile=’文件全名’ from pfile=’文件全名

數據庫在啓動的時候,會默認在$ORACLE_HOME/dbsspfile{實例名}.ora文件,如果沒有,它將尋找pfile文件,就是與8i兼容的init{SID}.ora的文本文件。當然,也可以通過指定的方式啓動數據庫。

Startup pfile=’文件全名’ or startup spfile=’文件全名

使用spfile最大的好處可能就是支持動態的參數修改,如

alter system set parameter_name=new_value scope=memory|spfile|both

這樣,通過命令方式可以修改參數生效或到參數文件。對於24*7的系統來說,這是一個不小的好處。

三、SGA動態內存分配

ORACLE9i中可以動態分配SGA,但是也是有限制的,你可以但分配SGA_MAX_SIZE大小,在這個尺寸之內,SGA的大小是可以動態分配的,可以根據不同的使用要求,來分配不同的SGA內存大小。

SQL> show parameter sga_max_size

?

NAME???????????????????????????? TYPE??????? VALUE

------------------------------------ ----------- --------------

sga_max_size???????????????????? ????big integer 1605044320?? //單位爲字節

?

SQL> show parameter db_cache_size

?

NAME???????????????????????????? TYPE??????? VALUE

------------------------------------ ----------- ---------

db_cache_size??????????????????????? big integer 671088640

?

SQL> alter system set db_cache_size=500M scope=both;

System altered.

注:db_cache_size也是9i新增加的參數,代替了以前版本中的db_block_buffers,可以通過該參數直接設置數據緩衝區的大小。

四、PGA自動管理

9i以前,PGA主要包括用戶信息,session信息,堆棧信息和Sort_Area_Size, Hash_Area_Size, Bitmap_Merge_Size, Create_Bitmap_Area_Size等池的大小。我們必須設置以上池的大小並監控它以獲得最佳性能。

但是,在9i以後,我們可以通過設置以下兩個參數以獲得PGA的自動管理:

a. WORKAREA_SIZE_POLICY
b. PGA_AGGREGATE_TARGET

如果WORKAREA_SIZE_POLICY=truePGA_AGGREGATE_TARGET=具體內存大小,ORACLE將自動管理PGA大大小,而忽略以上參數的設置。自動管理的PGA將採用自己的管理方法,可以獲得PGA的共享使用。

如果採用了自動管理,將有如下視圖可以監控

1.?????? V$SQL_WORKAREA

2.?????? V$SQL_WORKAREA_ACTIVE

3.?????? V$PROCESS contains new columns (PGA_USED_MEM, PGA_ALLOC_MEM AND PGA_MAX_MEM)

4.?????? V$PGASTAT

Oracle 9.2又增加了如下視圖
1. V$SQL_WORKAREA_HISTOGRAM
2. V$PGA_TARGET_ADVICE
3. V$PGA_TARGET_ADVICE_HISTOGRAM

五、表空間管理的本地化

9i,特別是920以後,如果系統表空間採用了本地管理,那所有的表空間都只能採用本地管理模式,如果顯示指定字典管理將顯示錯誤。其具體語法可以簡單的描述爲:

create tablespace tbsdata datafile '…' [ extent management local ] [ autoallocate ];

而對於指定每個擴展塊大小的創建策略,設立了新選項:統一擴展塊大小(uniform [size xxx[K|M]]),可覆蓋autoallocate選項,如果不加上具體的size xxx[K|M],缺省爲1M,這樣就不必考慮Oracle 8i中的如initial,next,pctincrease,maxextentsdefault storage參數應如何組合,事實上Oracle 8i的這些設置原本就沒有什麼意義。

如果未指定extent management的類型,如果又同時使用default storage選項,爲了兼容ORACLE8i,就有以下的判斷:

如果使用minimun extentOracle檢查是否minumum extent=initial=nextpctincrease0,如是,Oracle使用uniform選項,size=initial;如不是,Oracle忽略指定選項,使用autoallocate

如果未指定minimum extentOracle檢查是否initial=nextpctincrease0,如是Oracle使用uniform選項,size=initial;如不是Oracle忽略指定選項,使用autoallocate

爲了避免與Oracle 8i的習慣做法混淆,建議只使用Oracle 9i較簡潔的方法。

對於存儲少量靜態數據的表空間來說,如配置信息等,可簡單地寫爲:

create tablespace tbsdata datafile '…';

對於必須關心其擴展塊大小的表空間,如大批量的記錄或索引,可簡單地寫爲:

create tablespace tbsdata datafile '…' uniform size 10M;

另外一個問題就是,9i的臨時表空間將全部採用本地管理模式,所以在ORACLE8i往上升級的時候,臨時表空間將會出錯,因爲ORACLE這裏沒有提供向下的兼容性。

創建臨時表空間的語法在9i中被改爲如下:

create temporary tablespace tempfile ‘文件全名

六、自動回滾段管理

9i以前,回滾段全是手工管理與監控的,DBA需要花費一定的時間去管理與監控回滾段的性能,創建不好或管理不好的回滾段,將引起很大的性能瓶頸。從ORACLE9i,爲了更好的管理回滾段,ORACLE,默認採用自動回滾段管理。

自動回滾段管理可以最大限度的避免8i中比較有名的“快照太老”的錯誤,ORACLE9i通過如下四個初試化參數來設置自動回滾段管理:

undo_management??????????????????? string????? AUTO

undo_retention?????????????????????? integer???? 10800

undo_suppress_errors???????????????? boolean???? FALSE

undo_tablespace????????????????????? string????? UNDOTBS1

undo_management表明了回滾段管理採用自動方式,ORACLE建議採用自動方式,如果不是對數據庫非常瞭解,不要修改該參數。

undo_retention表明了回滾信息在回滾段中保持的時間,單位是秒,默認3個小時。

undo_suppress_errors表明不顯示某些錯誤信息,如對系統回滾段的操作將不顯示錯誤,雖然這個操作沒有成功。

undo_tablespace表明了使用自動回滾的表空間,DBA需要監控該表空間的大小。

自動回滾段的另外一個好處就是可以利用flashback來查看提交以前的數據或導出提交以前的數據,防止一定程度上的人爲錯誤。

七、自動段空間分配

ORACLE9i引進了段空間的自動分配(ASSM),ASSMtablespace是通過將SEGMENT SPACE MANAGEMENT AUTO子句添加到tablespace的定義句法裏而實現的(只能是本地管理的表空間)。通過使用位圖freelist取代傳統單向的鏈接列表freelistASSMtablespace會將freelist的管理自動化,並取消爲獨立的表格和索引指定PCTUSEDFREELISTSFREELIST GROUPS存儲參數的能力。

要注意,當表或者索引被分配到這個tablespace以後,用於獨立對象的PCTUSED的值會被忽略,而Oracle9i會使用位圖數組來自動地管理tablespace裏表格和索引的freelist。對於在LMTtablespace內部創建的表格和索引而言,這個NEXT擴展子句是過時的,因爲由本地管理的tablespace會管理它們。但是,INITIAL參數仍然是需要的,因爲Oracle不可能提前知道初始表格加載的大小。對於ASSM而言,INITIAL最小的值是三個區塊。

關於一個萬能的方法對於Oracle來說是否是最好的方法還有一些爭論。在大型數據庫裏,單獨的對象設置會帶來性能和存儲上的巨大不同。

在以前的版本中,在沒有多個freelist的時候,每個Oracle表格和索引在表格的頭部都曾有一個數據塊,用來管理對象所使用的剩餘區塊,併爲任何SQL插入聲明所創建的新數據行提供數據塊。當數據緩衝內的數據塊由於被另一個DML事務處理鎖定而無法使用的時候,緩衝區忙等待就會發生。當你需要將多個任務插入到同一個表格裏的時候,這些任務就被強制等待,而同時Oracle會在同時分派剩餘的區塊,一次一個。

有了ASSM之後,Oracle宣稱顯著地提高了DML併發操作的性能,因爲(同一個)位圖的不同部分可以被同時使用,這樣就消除了尋找剩餘空間的串行化。根據Oracle的測試結果,使用位圖freelist會消除所有分段頭部(對資源)的爭奪,還能獲得超快的併發插入操作

?

參考文獻:

http://www.happyit.net

http://otn.oracle.com/documentation/content.html

http://metalink.oracle.com/

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 機械工業出版社

ORACLE 9i UNIX 管理手冊 [] Donald K.Burleson 機械工業出版社

?

2004-8-6

聯合查詢
UNION
運算可以把多個查詢的結果合併到一個結果集裏顯示.
UNION
運算的一般語法:
[
]查詢1UNION[ALL]查詢2 UNION
:返回巴西所有供給商和客戶的名字和城市
SELECT CompanyName,City
FROMSuppliers
WHERE Country = ‘Brazil’
UNION
SELECT CompanyName,City
FROMCustomers
WHERE Country = ‘Brazil’
:
缺省的情況下,UNION子句不返回重複的記錄.如果想顯示所有記錄,可以加ALL選項
UNION
運算要求查詢具有相同數目的字段.但是,字段數據類型不必相同.
每一個查詢參數中可以使用GROUP BY 子句 HAVING 子句進行分組.要想以指定的順序來顯示返回的數據,可以在最後一個查詢的尾部使用OREER BY子句.

如果兩個表,例如supplycustom表,他們的列名必須相同纔可用UNION函數,否則不可以用。如果列名相同,但數據類型不同,則也可以執行union函數,但會重複的列出J

?

?

內連接時,返回查詢結果集合中的僅是符合查詢條件( WHERE 搜索條件或 HAVING 條件)和連接條件
的行。而採用外連接時,它返回到查詢結果集合中的不僅包含符合連接條件的行,而且還包括左表(左外
連接時)、右表(右外連接時)或兩個邊接表(全外連接)中的所有數據行。

?

例如兩個表supplycustom

SQL> select * from supply;

?

COMPANYN CITY

-------- --------

IBM????? manhaton

HP?????? newyork

MS?????? newyork

?

SQL> select * from custom;

?

COMPANYN CITY

-------- --------

IBM????? manhaton

MS?????? manhaton

SUN????? kalifnio

?

SQL> select * from supply union select * from custom;

?

COMPANYN CITY

-------- --------

HP?????? newyork

IBM????? manhaton

MS?????? manhaton

MS?????? newyork

SUN????? kalifnio

?

SQL> select * from supply s left join custom c on s.COMPANYNAME=c.COMPANYNAME;

?

COMPANYN CITY???? COMPANYN CITY

-------- -------- -------- --------

IBM????? manhaton IBM????? manhaton

MS?????? newyork? MS?????? manhaton

HP?????? newyork

SQL> select * from supply s,custom c where s.COMPANYNAME=c.COMPANYNAME(+);

?

COMPANYN CITY???? COMPANYN CITY

-------- -------- -------- --------

HP?????? newyork

IBM????? manhaton IBM????? manhaton

MS?????? newyork? MS?????? manhaton

?

SQL> select * from supply s full outer join custom c on s.city=c.city;

?

COMPANYN CITY???? COMPANYN CITY

-------- -------- -------- --------

IBM????? manhaton IBM????? manhaton

IBM????? manhaton MS?????? manhaton

MS?????? newyork

HP?????? newyork

????????????????? SUN????? kalifnio

?

SQL> select * from supply cross join custom;

?

COMPANYN CITY???? COMPANYN CITY

-------- -------- -------- --------

IBM????? manhaton IBM????? manhaton

HP?????? newyork? IBM????? manhaton

MS?????? newyork? IBM????? manhaton

IBM????? manhaton MS?????? manhaton

HP?????? newyork? MS?????? manhaton

MS?????? newyork? MS?????? manhaton

IBM????? manhaton SUN????? kalifnio

HP? ?????newyork? SUN????? kalifnio

MS?????? newyork? SUN????? kalifnio

?

已選擇9行。

?

SQL> select * from supply s inner join custom c on s.COMPANYNAME=c.COMPANYNAME;

?

COMPANYN CITY???? COMPANYN CITY

-------- -------- -------- --------

IBM????? manhaton IBM????? manhaton

MS?????? newyork? MS?????? manhaton

?

發佈了27 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章