oracle學習入門系列之五
內存結構、數據庫結構、進程
關於這個話題,網上一搜絕對一大把,更別提書籍上出現的了,還有很多大師們的講稿。但是我們不去管那些,按照我們自己節奏記出特性、記出精彩來。
首先插入本系列第一張圖片,圖一(絕對來自官網),看蛤蟆對於圖片使用是多麼小心的,如果大伙對這個圖已有自己獨到的理解,那麼可直接跳過本篇筆記吧,當然溫故而知新也未嘗不可,知恥而後勇….額,而來知恥?
這個圖1從總體上描述了Oracle數據庫的大概了,包含有內存結構,數據庫文件,進程及客戶端。雖然不是非常詳細但是蛤蟆覺得該圖是在是理解ORACLE數據庫入門的好圖。
那麼我們一起圍觀下該圖到底說了些什麼。
服務進程,這裡展開就是服務進程是專用服務進程還是共享,後續會慢慢道來。
內存結構,內存結構中主要包含PGA和SGA,PGA是為客戶端接入時候服務,SGA是數據庫運行服務的,這些在機器下電後就消失了。
還有主要的6個進程PMON,SMON,DBWR,LGWR,CHPT,Arcn,在啟動數據庫的時候才會有這些進程。
最下面就是存放在持久化介質上文件了,有歸檔日志,數據文件,參數文件,密碼文件等,不隨機器下電而消失的。
途中有2個在Oracle中非常重要的概念,實例和數據庫:
實例是oracle 創建的進程和內存結構的組合。
數據庫是由一組文件組成的,對數據庫的所有操作都是需要通過實例來完成了。通常數據庫和實例是一一對應的。例外就是RAC了,RAC下一個數據庫就對應了多個實例。
實例和數據庫關系打個比方就是發動機和汽車的關系。汽車就是數據庫,就在那裡,但是動不了,只有發動機發動了,汽車才能動起來。一般情況下一個汽車一個單缸發動機;但是也可以是多缸的嘛,如6缸發動機什麼的。
接下去看邏輯數據庫結構。
放入第二章圖,如下圖2,如來自互聯網
這裡需要提一些概念了,都是ORACLE數據庫中最基本而且需要一直掌握的概念,是一直,死都不能忘了,如果擔心自己忘記就記下來把。這裡提到的概念是一通百通的,很多可以適用到其他數據庫中的,記住後我們後續學習必將事半功倍。
我們從最下面開始介紹吧,枯燥但不乏味的哈~
數據塊,data block,是oracle數據塊的存儲基礎,有若干字節組成。又是若干,到底是多少個字節呢?一般常用的是8KB,4KB的了,在創建數據庫的時候可以指定。一旦指定就不能改變了,不過即使在4KB的數據庫中,我們也可以指定創建8KB的表空間的,只要我們內存結構中存在8KB的緩存。
數據塊類似操作系統中的塊大小,通常ORACLE數據庫塊大小會是操作系統塊大小的整數倍,其中好處就無需多說了。
蛤蟆自身工作經驗來看,在OLTP模型上,4KB、8KB及16KB下性能相差不是特別明顯。
不過原則是塊尺寸是處理Oracle的更新、選擇或者插入數據事務的最小單位,且訪問很隨機,則選擇塊較小的塊尺寸;如果行比較小且訪問主要是連續,或者如果有較大的行,則用較大的塊尺寸。
區,extent,是兩個或者多個相鄰的ORACLE數據塊,他是空間分配的單元。概念總是如此的明了,3點關鍵。
a) 2個或2個以上
b) 相鄰的數據塊
c) 空間分配單元
數據塊是存儲單元,區是分配單元。看著概念重不重要的,從概念我們就知道,ORACKE分配空間的時候至少2個數據塊起步的。要是申請一個數據塊,那麼不好意思啦,就是不給。
就像小時候向爸爸媽媽要零花錢,
我們:“媽,給我5分錢,買個蘿卜絲吃”
老媽:“!@#¥%……,沒有5分”
我們:“一毛也行”
老媽:“好吧,又買兩包蘿卜絲?,給你1毛”
段是分配給某個邏輯結構的一組區。
2個關鍵點
a) 分配給某個邏輯結構
b) 一組區
ORACLE數據庫對象,主要就是如下10個了。
1) 表
2) 約束條件:保證數據完整性。
3) 視圖:虛表,命名的查詢語句。
4) 索引:加速查詢(加快查詢的速度)。
5) 序列:一串連續遞增或遞減的數字,步長相同,(代理鍵) 。
6) 同義詞:一個對象的另外一個叫法(對象的別名)。
7) 存儲過程:用於操作
8) 函數:用作復雜運算的。用於計算。
9) 觸發器:由事件觸發的存儲過程。
10) 包
對數據庫的操作可以基本歸結為對數據對象的操作,這個對象蛤蟆也不知道如何去定義它。對象也是一個邏輯結構,是建立於段之上的,有頭有臉的結構。
表空間是一組數據文件,通常由相關的段組成。表空間是包含物理數據文件的邏輯實體。表空間存儲數據庫的所有可用數據。
下節中就能看到表空間和物理數據文件的對應關系。表空間也是一個邏輯結構是,數據庫下最大的邏輯結構了。
數據庫創建完後會有如下表空間
a) System表空間
b) Sysaux 表空間
c) 撤銷Undo表空間
d) 臨時temporary表空間
上節介紹了oracle數據庫的邏輯結構,那麼接下去必須得看下,邏輯結構和物理存儲結構是如何對應的。
首先在通常情況下我們可以這樣理解,ORAC LE數據庫由表空間組成;所以和物理數據庫結構相關的從表空間開始了。
先看如下圖3:
從上圖可以看出,邏輯結構比物理結構復雜了些許。
物理結構上就兩個東西 操作系統塊和文件。上節中提到數據庫塊是操作系統塊的整數倍,從圖中也能反映一二。
這裡蛤蟆重點解釋下ORACLE數據庫中的文件。
數據文件一般是數據庫最大的物理存儲部分,一個數據文件只能屬於一個數據庫。一個或者多個數據文件構成成為表空間的實體。
我們創建一個表空間時候,讓他擁有一個2G大小的數據文件,那麼該表空間就能存放2G大小的數據量,有一天耗盡了這2G,那麼再增加一個數據文件給這個表空間,當然也可以擴大原先數據文件的大小。
注意:上篇提到了對象如索引、表等,雖然也是存在表空間所屬的數據文件中,但是這些對象本身不會指定要存放在那個數據文件上,數據文件只與表空間關聯。
數據庫中執行如下查看數據文件所在
SQL>selectname from v$datafile;
一看這個文件,蛤蟆就不禁感歎:如此之小,確如此重要啊。小身材,大作用。
這個控制文件,管理了數據庫的狀態,非常重要,一般管理員都會進行至少3份備份。
控制文件包含了數據文件和重做日志文件的名字、位置、日志序號、備份等詳細信息,以及所有重要的SCN(系統更改號)。數據庫在操作過程中進程不斷的更新控制文件。
控制文件中的檢查點信息使ORACLE能確定從聯機重做日志文件中需要返回多少以便恢復數據。此外,在啟動oracle實例時,通過控制文件,確定數據庫操作必須打開的所有數據文件和重做日志文件。
你看,重要不?
查看控制文件所在
SQL>selectname from v$controlfile
日志文件其實准確的是重做日志文件,記錄了對數據庫做的全部更改,有助於恢復數據庫。如果日志文件寫滿後就會進行歸檔,歸檔的日志文件叫做歸檔重做日志,正在記錄的日志文件叫做聯機重做日志文件。
Oracle要求數據庫至少兩個重做日志組,每個至少一個單獨的日志文件。在歸檔的時候當前日志組就不能用了,所以需要有第二個日志組來接上。這樣循環,生生不息。
考慮到日志文件恢復數據庫的作用,一般建議多路復用重做日志,把日志副本存放到不同的磁盤上,保證不會輕易丟失。
查看重做日志文件所在
SQL>select member from v$logfile;
還有一些文件,蛤蟆先簡單帶過一下吧,後續咱們再深入之。
SPFILE,PFILE,密碼文件,告警日志文件,跟蹤文件,備份文件等。
SPFILE是oracle實例的初始化參數,這個文件是二進制文件無法手動編輯,我們可以通過命令從SPFILE來生成PFILE,PFILE可以支持手動編輯。下節中內存結構中的組件大小都可以在SPFILE或者PFILE中進行設定。
密碼文件是授予SYSDBA或SYSOPER管理權限的數據庫用戶名字,和數據庫安全相關,後續蛤蟆會和大伙一起搗鼓搗鼓。
告警日志文件,蛤蟆喜歡叫他alert日志。捕捉了oracle實例運行期間的主要更改和事件。包含日志切換、錯誤、告警和其他信息,也是數據庫錯問題時候,蛤蟆第一時間查看地方,大伙沒事可以進去看看也。Alert日志文件路徑:
$ORACLE_BASE/diag/rdbms/[SID]/trace/alert_[SID].log。
跟蹤文件,Oracle各類內部結構中所包含的信息轉儲(dump)到跟蹤文件中,以便用戶能根據文件內容來解決各種故障。
備份文件,顧名思義,因為備份數據操作得到的文件。
內存結構也是ORACLE數據庫實例的組成部分。這個內存結構可以讓用戶之間共享可執行代碼,可以將數據庫更改寫入內存區域等,讓數據庫性能提升好幾個數量級。
我們看圖4
一圖勝過千言萬語啊,一看就明白了數據庫內存結構包括PGA和SGA,那麼問題來了,具體呢?
SGA是實例中最重要的內存部件了,特別是在OLTP數據庫系統中,比PGA要大很多。在數據倉庫環境下,PGA可能就是更重要的ORACLE內存區域。
保存從文件中讀取的數據塊副本,提高讀取性能。
當然數據庫緩沖區本身還可以細化成:可用緩沖區,髒緩沖區,釘住緩沖區。
緩沖區的主要目的是最小數據未命中率和磁盤IO操作。
可以將一個緩沖區分成多個緩沖區提供給不同的對象使用,也可以設置多個數據庫塊尺寸的緩存區(如4KB,8KB,16KB的)。
共享池是保持可執行PL/SQL代碼和SQL語句,以及數據字典表的信息。其可以分為庫高速緩存和字典高速緩存。
注:數據字典是ORACLE維護的一組關鍵表,包含了又關數據表、用戶、權限等重要的元數據。
該池可以減少相同代碼的編譯,減少硬解析從而減少內存和CPU資源。
蛤蟆就知道了數據字典和庫高速緩存的低命中率的解決方法是相同的,即增加共享池的尺寸。
我們待會回將日志寫入進程,因為日志寫入進程的刷新頻率,該區大小不必太大,基本幾M就搞定了。
為JVM何基於JAVA的應用保留。
在使用並行查詢時候才需要使用大池。此外使用RMAN和共享服務器配置也需要建議配置大池。
實現在不同數據庫之間和不同環境之間共享數據。
用戶啟動會話時為每個用戶創建一個程序全局區。PGA保存ORACLE為用戶創建的專用服務器進程的數據和控制信息。PGA是獨占的不能共享,除非使用一個共享的服務器配置。
PGA可以存放用戶的游標,不與其他用戶共享,此外還會涉及一些排序類的內存密集型操作。
概念介紹大伙看看樂一樂好了,當前不需要太較真。
進程是Oracle數據庫實例的一部分,我們說過oracle數據庫實例由內存結構和進程組成。
Oracle進程其實可以分為兩種,一種是用戶進程,用於連接用戶和數據庫;另一種是oracle進程,用於執行數據庫的所有實際操作(讀寫數據文件,寫日志等)。這裡蛤蟆來聊聊最主要的幾個後台進程,其他的進程咱有機會再說。
進程是什麼呢?這個蛤蟆就不說了哈
咱們直接進入正題,如下進程都可以在安裝ORACLE數據的系統中執行
#ps –ef | grep ora_
來查看。
這個進程的作用是將在內存中的數據寫入到磁盤中,使得對數據庫的修改持久化。因為考慮到性能問題,並不是對數據庫的所有修改多會直接寫磁盤,而是保留在內存中,等時機成熟才進行批量刷入到磁盤中,這對性能提升還是大大的。
這個時機就是如下三種情況:
a) 數據庫發布檢查點
b) 內存緩沖區沒有可用空間
c) 3秒
以上3點,任何一點滿足即可。
考慮到有些系統每次刷入的數據量較大,ORACLE就支持多個進程一起寫。通過在DB_WIRTER_PROCESSES參數在PFILE中設定,前提是系統支持異步IO,不然不如只用一個寫進程。
類似數據寫進程,將重做日志在內存中的緩存寫入到磁盤中。這個寫特點是100%順序寫。如果日志文件不能被寫入,那麼數據庫就會停止工作了,當然這種情況極小發生。畢竟好端端的怎麼會突然不能被寫入了呢。
日志寫也是有時機的類似數據寫進程,這進程有四個機會點了
a) 3秒
b) 緩存區到三分之一
c) 數據寫進程觸發(先完成日志寫進程,方進行數據寫進程,針對這個有個寫前協議)
d) 事務提交,將提交記錄寫到重做日志
注意:重做日志文件可能包含提交以及未提交的事務記錄。
這是系統監控進程了,並非一直工作,周期性巡檢。主要處理
a) 實例崩潰重啟後,是否一致
b) 合並可用區(我們說過區是相鄰的數據塊嘛)
c) 清除不必要的臨時段
這個進程用於清除失敗的用戶進程,保證數據庫釋放死進程占用的資源。這個進程和SMON一樣,一般是處於不活動的,但是會周期性的進行巡檢,類似魔獸世界中豬頭監工,不干活,周期性的走走,看看誰在偷懶,偷懶的它就動手。
如果可以蛤蟆也希望變成PMON,SMON,他們兩兄弟干活真實輕松啊,一看就是領導。
通知數據庫寫進程,這個還會觸發日志寫進程的。該進程的作用是同步緩存區高速緩存信息與數據庫磁盤上的信息。
該進程具體是做了如下4個事情:
a) 日志緩沖寫到日志文件
b) 檢查點記錄寫入日志文件
c) 刷數據緩存到磁盤中
d) 更新數據文件和控制文件的頭
這個進程在系統以歸檔方式運行時才有,負責將填滿的日志文件歸檔。就是將聯機日志文件的內容生成一個歸檔日志文檔。如果需要,可以同時設置多個進行進行歸檔操作。
這個進程在切換日志的時候開始干活。
如果我們在非歸檔模式運行,那麼壓根就沒有這個進程了,不過生產系統必須以歸檔模式運行,不然後果不堪設想,蛤蟆自己玩的系統崩潰也沒事的哈哈。
其他進程在此就不啰嗦了,後續自然會涉及。這篇到此結束~如果大伙感興趣就看下回筆記。