目錄
Oracle Instance
- SGA
* shared pool
* Database Buffer
* Redo Log Buffer
* Large Pool
* Java Pool
* Stream Pool - Background Process
* PMON
* SMON
* DBWR
* LGWR
* CKPT
* ARCn
Database
正文
Oracle的體系結構大體上分為兩部分:Instance(實例)和 Database(數據庫)。
如圖1所示:
圖1 Oracle 數據庫體系結構
我們平時說的Oracle Server(Oracle服務器)就是由 Oracle Instance 和 Oracle Database 組成的,如圖2:
圖2 Oracle Server
Oracle Instance |
SGA
SGA包含6 個基本組件:Shared Pool(Library Cache,Data Dictionary Cache)、Database Buffer Cache、Redo Log Buffer、Java Pool、Large Pool、stream pool。
下面將分別介紹這6個基本組件的功能。
1) shared pool(共享池)
-
共享池是對 SQL、PL/SQL 程序進行語法分析、編譯、執行的內存區域。
-
共享池由 Library Cache(庫緩存)、Data Dictionary Cache(數據字典緩存)和 Server Result Cache(結果緩存)等組成。
-
共享池的大小直接影響數據庫的性能。
shared pool 的各組成部分有哪些作用呢?
-
Library Cache: SQL 和 PL/SQL 的解析場所,存放着經過編譯解析后的SQL和PL/SQL語句的內容,以備所有用戶共享。
* 如果下次再執行同樣的 SQL 語句的時候,就不需要解析了,立即從 Library Cache 獲取執行。
* Library Cache的 SIZE 會決定着編譯解析 SQL 語句的頻度,從而決定了性能。
* Library Cache中又包含兩部分內容:Shared SQL Area和Shared PL/SQL Area。 -
Data Dictionary Cache: 存放重要的數據字典信息,以備數據庫使用。
* Data Dictionary是使用最頻繁的,幾乎所有的操作都需要到數據字典去查詢。為了提高訪問Data Dictionary的速度,此時需要一個Cache,需要的時候訪問內存即可。
* Data Dictionary Cache里面的信息包含了Database Files、Tables、Indexes、Columns、Users、Privileges和其他的數據庫對象。 -
Server Result Cache: 存放服務器端的 SQL 結果集及 PL/SQL 函數返回值。
看了上面的講解,或許會覺得有些抽象,下面將通過一個例子進行講解。
假設在客戶端提交一個命令,如下:
SELECT ename,sal FROM emp WHERE empno=7788;
如果數據庫是第一次被提交這條語句,則需要進行解析,解析過程分為硬解析和軟解析。
- 硬解析:檢查語法、語義、權限,分析綁定變量等,最終生成一個執行計划;
- 軟解析:依據執行計划去具體執行它。若是select語句,執行完后還會返回結果集,若是update、delete語句則無需返回結果集。
Library Cache會把這條 sql 語句和執行計划裝入其中。
裝入這些東西有什么作用呢?
下次再敲一摸一樣(標點符號、大小寫、空格完全一致)的語句時,就不需要硬解析了。
小問答:
如果此時客戶端再提交一條命令:
select ename,sal from emp where empno=7788;
猜測一下,這條語句需要被解析嗎?
答案:需要。
小說明:注意哦,語句必須完全一樣才不需要解析哦。標點符號、大小寫、空格等都要完全一致哦!平時規范書寫的好處在這里就體現啦。
前面有說到,若是 select 語句,執行完后還會返回結果集。那結果集存放在哪里呢?
select ename,sal from emp where empno=7788;
該語句執行返回的結果集將存放在 Server Result Cache 中。
2) Database Buffer Cache (數據緩沖區)
- Database Buffer Cache用於存儲從磁盤數據文件中讀入的數據,為所有用戶共享。
- Server Process(服務器進程)將讀入的數據保存在數據緩沖區中,當后續的請求需要這些數據時可以在內存中找到,則不需要再從磁盤讀取。
- Database Buffer Cache 的大小對數據庫的讀取速度有直接的影響。
小說明:邏輯讀(從內存讀)的速度是物理讀(從磁盤讀)的1萬倍呦,所以還是想辦法盡量多從內存讀哦。
例如用戶訪問一個表里面的記錄時,數據庫接收到這個請求后,首先會在Database Buffer Cache中查找是否存在該數據庫表的記錄,如果有所需的記錄就直接從內存中讀取該記錄返回給用戶(有效提升了訪問的速度),否則只能去磁盤上去讀取。
繼續看上面的例子:
select ename,sal from emp where empno=7788;
該條語句以及它的執行計划被放在Library Cache里,但語句涉及到的數據,會放在 Database Buffer Cache 里。
小問答:
Database Buffer Cache是怎么工作的呢?
這就要說一說Database Buffer Cache的設計思想了。
磁盤上存儲的是塊(block),文件都有文件號,塊也有塊號。
若要訪問磁盤上的塊,並不是CPU拿到指令后直接訪問磁盤,而是先把塊讀到內存中的Database Buffer cache里,生成副本,查詢或增刪改都是對內存中的副本進行操作。如圖3所示。
另外,如果是增刪操作,操作后會形成臟塊,臟塊會在恰當時機再寫回磁盤原位置,注意哦,可不是立刻寫回呦。
也許你會問,為什么不立刻寫回呢?
因為:
(1)減少物理IO;
(2)可共享,若后面又有對該塊的訪問,可直接在內存中進行邏輯讀。
圖3 訪問磁盤塊
小問答:
為什么要通過內存訪問數據塊,而不是CPU直接訪問磁盤呢?
答:因為相較於CPU,IO的速度實在是太慢了,CPU的速度是IO 的100萬倍呢?如果CPU直接訪問磁盤的話,會造成大量的IO等待,CPU的利用率會很低。所以,利用速度相當的內存(CPU速度為內存的100倍)做中間緩存,可以有效減少物理IO,提高CPU利用率。
但是,這里會有一個問題。前面說到查詢或增刪改都是對內存中的副本進行操作,當增刪改操作產生臟塊時不會立刻寫回磁盤。
小問答:
我們設想一下,如果在 Database Buffer Cache 中存放大量未來得及寫回磁盤的臟塊時,突然出現系統故障(比如斷電),導致內存中的數據丟失。而此時磁盤中的塊存放的依然是修改前的舊數據,這樣豈不是導致前面的修改無效?
要怎樣保持事務的一致性呢?
答:如果我們能夠保存住提交的記錄,在 Database Buffer Cache 中一旦有數據更改,馬上寫入一個地方記錄下來,不就可以保證事務一致性了嘛。
小說明:Instance在斷電時會消失,Instance在內存中存放的數據將丟失。這就需要 Redo Log Buffer 發揮它的作用啦。
3)Redo Log Buffer (重做日志緩沖區)
- 日志條目(Redo Entries )記錄了數據庫的所有修改信息(包括 DML 和 DDL),一條Redo Entries記錄一次對數據庫的改變 ,為的是數據庫恢復。日志條目首先產生於日志緩沖區。
- 日志緩沖區較小,它是以字節為單位的,它極其重要。
- 在Database Buffer Cache中一旦有數據更改,馬上寫入Redo Log Buffer,Redo Log Buffer在內存中保留一段時間后,會寫入磁盤,然后歸檔(3級結構)。
圖4 三級結構
4)Large Pool (大池)(可選)
- 為了進行大的后台進程操作而分配的內存空間,與 shared pool 管理不同,主要用於共享服務器的 session memory,RMAN 備份恢復以及並行查詢等。
5)Java Pool (Java 池)(可選)
- 為了 java 虛擬機及應用而分配的內存空間,包含所有 session 指定的 JAVA 代碼和數據。
6)Stream Pool (流池)(可選)
- 為了 stream process 而分配的內存空間。stream 技術是為了在不同數據庫之間共享數據,因此,它只對使用了 stream 數據庫特性的系統是重要的。
Background process
在正式介紹 Background Process 之前,先簡單介紹 Oracle 的 Process 類型。
Oracle Process 有三種類型:
-
User Process
* 屬於客戶端的 Process,客戶端要與服務器連接,在客戶端啟動起來的進程就是 User Process ;
* 一般分為三種形式(sql*plus, 應用程序,web 方式(OEM));
* User Process 不能直接訪問Oracle 。 -
Server Process
* 屬於服務器端 Process,用於接應User Process 發出的請求;
* 給用戶分配 PGA(程序全局區)。 -
background process
Oracle Instance的重要組成部分。下文會對其做詳細講解。
【User Process 不能直接訪問 Oracle,必須通過相應的 Server Process 訪問實例,進而訪問數據庫。】
小補充:
Connection & Session
Connection是指一個Oracle的客戶端和后台和后台的進程(Server Process)建立的TCP連接。如圖 5 所示:
圖5 Connection
Connection 建立過程可簡單描述如下:
1.首先建立 TCP 連接,Oracle 對用戶的身份進行認證、進行安全審計等等;
2.當這些都通過后, Oracle 的 Server Process 才會允許客戶端使用Oracle提供的服務;
3.當 Oracle 的連接建立起來以后,就意味着開始了一個 Session (會話),當連接斷開的時候這個會話就消失了。
【用戶登錄到 Oracle Server 就是 User Process 和 Server Process 建立Connection。】
Session 是和 Connection 相輔相成的。Session信息會存儲在 Oracle 的 Data Dictionary 中。
可通過圖 6 直觀看出 Connection 和 Session 的區別。
圖6 Connection & Session
Background Process(后台進程)主要包括:PMON(進程監控器進程)、SMON(系統監控器進程 )、DBWR( 數據庫寫入程序進程)、LGWR(日志寫入程序進程)、CKPT(檢查點進程)。
1)PMON(Process Monitor)
PMON的主要作用如下:
- 監控各個Oracle后台進程是否正常,發現異常的進程將其清除掉,重新生成該進程。
(說明:當用戶進程斷掉時,Server Process 留着就沒用了,但是還占着空間,PMON 會定時檢查 Server Process ,如果和 User Process 連接不上了,PMON 會把 Server Process 收回,把 PGA 空間收回,里面的鎖也收回。) - 監控空閑會話是否到達閥值。
- 動態注冊監聽。
2)SMON(System Monitor)
SMON的主要作用如下:
- 當Oracle運行時突然宕機,下次啟動需要實例恢復(Instance Recovery),SMON負責實例恢復的全程監控;
- 當Oracle運行時突然宕機,在下一次啟動Oracle Instance的時候,它里面一些沒有釋放的資源會由SMON進行清理;
- 一些事務失敗的時候也由SMON進行清理;
- 內存空間很分散(不連續)時需要SMON將這個分散的空間整合起來;
- 釋放不再使用的臨時段(Segment)。
3)DBWR(Database Writer)
DBWn是Oracle中工作最繁重的進程。主要作用如下:
- 將 Database Buffer Cache 中的臟塊(Dirty Buffer)寫到 Data File 中。
- 釋放Data Buffer Cache空間。
小說明:
如果數據庫的負荷比較大,來自於客戶端的請求比較多,存在大量的IO操作,需要頻繁的將緩沖區的內容寫到磁盤文件上,那么這時就可以配置多個DBWn(一共Oracle支持20個DBWn,DBW0-DBW9,DBWa-DBWg)。通常一個中小型的Oracle只需要一個DBW0 Process就可以了。
注意:以下幾種情況發生時,都會觸發DBWR Process將 Database Buffer Cache 的內容寫到Data Files :
- Checkpoint Occurs
- Dirty Buffer reach threshold
- There are no free Buffers
- Timeout occurs
- RAC ping request is made
- Tablespace OFFLINE
- Tablespace READ ONLY
- Table DROP or TRUNCATE
- Tablespace BEGIN
- BACKUP
小補充:
服務器進程對數據文件執行讀操作,而 DBWR 負責對數據文件執行寫操作。
小問答:
Commit 時 DBWR 有何動作?
答:什么也不做!
4)LGWR(LOG Writer)
Oracle Instance中只有一個LGWR Process,這個Process的工作和DBWR Process類似。主要作用如下:
- 將 Redo Log Buffer 中的內容寫入到 Redo Log Files 中(必須在 DBWR 寫臟塊之前寫入日志)。
(Redo Log Buffer 是一個循環的Buffer,對應的 Redo Log Files 也是一個循環的文件組,從文件頭開始寫,當文件寫滿了,又會從文件頭開始寫,會把前面的內容覆蓋掉,為了避免將 Redo Log Files 覆蓋掉可以選擇將其寫入到 Archived Redo Log Files 中。)
注意:以下幾種情況發生時,都會觸發LGWR Process將 Redo Log Buffer 中的內容寫到 Redo Log Files :
- At Commit
- When one-third full
- When there is 1 MB of redo
- Every three seconds
- Before DBWn writes
怎么保證提交的事務永久保留呢?
答:以執行update操作為例 。
1. 當執行提交語句的時候,修改已經寫到 Redo Log Buffer 里了;
2. 當看到返回提交成功時,說明修改已經寫到磁盤 Redo Logfile 里了;
3. 所以提交成功后,改動已經同步到磁盤了,不會丟了。
5)CKPT(Checkpoint)
CKPT的主要作用如下:
- 生成檢查點, 通知或督促 DBWR 寫臟塊;
*完全檢查點:保證數據一致性。
*增量檢查點:不斷更新控制文件中的檢查點位置,當發生實例崩潰時,可以盡量縮短實例恢復的時間。 - 在Data File的在文件頭更新檢查點信息;
- 在Control File中更新檢查點的信息。
6)ARCn(Archiver)
- ARCn是一個可選的后台進程(幾乎可看作必選進程)。
- Oracle可以運行在兩種模式下:ARCHIVELOG MODE(歸檔模式)、NOARCHIVELOG MODE(非歸檔模式)。DBA 必須做出的一個重要決策是,配置數據庫在ARCHIVELOG模式下運行,還是在NOARCHIVELOG模式下運行。
- 聯機重做日志文件填滿后,oracle實例開始寫入下一個聯機重做日志文件。從一個聯機重做日志文件切換到另一個聯機重做日志文件的過程稱為日志切換。
ARCn的主要作用如下:
當Oracle運行在歸檔模式時
- ARCn進程在每次進行日志切換時都會開始對已填滿的日志組進行備份或歸檔。
- ARCn進程會在可以重新使用日志之前自動歸檔重做日志文件,因此會保留對數據庫所做的所有更改。這樣,即使磁盤驅動器損壞,也可以將數據庫恢復到故障點。
通過上面的學習,先把圖 1 更新如下:
圖7 Oracle 數據庫體系結構
Database |
Database 其實就是由一堆物理文件組成的,主要是用於存儲數據,Database 中主要包含三種類型的文件:Data Files、Control Files、Redo Log Files。
另外還有Parameter File、Password File、Achieved Log Files等。
1)Data Files(數據文件)
- Data Files 就是用於存儲數據的,Table 中的數據都是保存在 Data Files 中的。
- 1個 Data File 對應磁盤上的 1 個物理操作系統文件。
- Data Files 中頻繁訪問的數據塊緩存在 Database Buffer Cache 中。
- 新的數據塊不會立刻寫出到 Data Files,而是在 DBWR處於活動狀態時再寫出。
2)Control Files(控制文件)
- Oracle為了操作Data File,提供了一些 Control Files,這些 Control Files 主要是記錄數據庫的一些控制信息。
- 用於維護數據庫對象的狀態,維護數據庫的元數據(數據庫自身物理結構的數據:數據庫名稱、數據庫創建時間、所有數據文件和重做日志文件的名稱及位置)。
3)Redo Log Files(重做日志文件)
- Redo Log Files 記錄着數據庫的改變,如果向數據庫中放入數據或者是修改里面的數據,只要對數據庫作了修改(insert,delete,update),那么就要將修改之前的狀態、修改之后的狀態都記錄在 Redo Log Files 中,其作用就是恢復Data File。
* 例如:數據庫有一個事務需要提交,但是提交失敗了,事務就要回滾,那么事務回滾的依據就來自於這個 Redo Log Files。Redo Log Files 中記錄着數據庫的改變,關於這個事務的改變,如果需要回滾就需要把Redo Log Files中的數據取出來,依照 Redo Log Files 中的數據把 Data Files 恢復到修改之前的狀態。
* 有 3 種狀態:Active、Inactive、Current 。
4)Parameter File(參數文件)
- 任何一個數據庫都必須要有參數文件,這個參數文件規定了Oracle中的一些基本的參數、初始化的參數的值。
5)Archived Log Files(歸檔日志文件)
- Archived Log Files 和 Redo Log Files 是相輔相成的,Redo Log Files 其實是一個反復利用的過程,會有幾個(一般為3個)固定的文件,這些固定文件會被依次使用,用滿了以后,Oracle就會再次寫這個文件頭,就把以前的東西沖掉了。為了進一步加強數據庫的備份恢復能力,在覆蓋之前把這些修改的信息都歸檔到 Archived Log Files 中。
6)Password File(密碼文件)
- 用戶客戶端連接到后台數據庫系統時候存儲口令的。
小問答:
Instance 和 Database 的對應關系是怎樣的呢?
答:Instance :Database = n :1
1個 Instance 只能屬於1個數據庫,可以多個 Instance 同時訪問1個數據庫。
小補充:
Oracle 的內存結構(Memory Structure)
Oracle 的 Memory Structure 實際上包含兩部分內容:SGA和PGA
SGA(System Global Area系統全局區)
- 一個 Oracle Instance 對應一個SGA,SGA 在Oracle Instance啟動的時候被分配,SGA 是Oracle Instance 的基本組成部分。
- 一個 Oracle Instance 僅有一個 SGA,SGA是一個非常大的內存空間,甚至可以占據物理內存的80%。
PGA(Program Global Area程序全局區)
- 一個 Server Process 啟動的時候就會分配一個 PGA。在 Oracle Instance 中 PGA 可能會很多。例如啟動10個Server Process就會有10個PGA。
- PGA 存放用戶游標、變量、控制、數據排序、存放 hash 值。
- 與 SGA 不同,PGA 是獨立的,非共享。是分配給一個進程並歸該進程私有的內存區域。
用戶與 Oracle 服務器的連接方式
專用連接模式(Dedicated Server Process)
- 用戶在客戶端啟動了一個應用程序,例如 sql*plus,就是在客戶端啟動一
個 User Process ,與 oracle 服務器端連接成功后,會在服務器端生成一個 Server Process ,該 Server Process 作為 User Process 的代理進程,代替客戶端執行各種命令並把結果返回給客戶端。會話與專用服務器之間存在一對一的映射。 - User Process 一旦中止,與之對應的Server Process立刻中止。
- 專用連接的 PGA 的管理方式是私有的。
- Oracle 缺省采用專用連接模式。
共享連接模式(shared server process)
- 多個 User Process 共享一個 Server Process。
- 它通過調度進程(Dispatcher)與共享服務器連接,共享服務器實際上就是一種連接池機制(connectionpooling),連接池可以重用已有的超時連接,服務於其它活動會話。但容易產生鎖等待。
- 此種連接方式現在已經很少使用了。
- 所有調度進程(Dispatcher)共享一個公共的請求隊列(resquest queue),但是每個調度進程都有與自己響應的隊列(Response Queue)。
- 在共享服務器中會話是在 SGA 中的(UGA)存儲信息,而不像專用連接那樣在 PGA 中存儲信息,這時的 PGA 的存儲結構為堆棧空間。
駐留連接池模式(Database Resident Connection Pooling,簡稱 DRCP)
- 適用於必須維持數據庫的永久連接。
- 結合了專用服務器模式和共享服務器模式的特點,它提供了服務器連接池,但是放入連接池的是專用服務器。
- 它使用連接代理(而不是專用服務器)連接客戶機到數據庫,優點是可以用很少的內存處理大量並發連接(11g 新特性,特別適用於 Apache 的 PHP 應用環境)。