詳解Oracle實(shí)例內(nèi)存結(jié)構(gòu)和進(jìn)程結(jié)構(gòu)
由于內(nèi)存結(jié)構(gòu)和進(jìn)程結(jié)構(gòu)關(guān)系較緊密,進(jìn)程會(huì)作用到對(duì)應(yīng)的內(nèi)存區(qū)域,比如數(shù)據(jù)庫(kù)寫(xiě)入器作用到數(shù)據(jù)庫(kù)緩沖區(qū)緩存中,日志寫(xiě)入器會(huì)作用到日志緩沖區(qū),所以在這里我把內(nèi)存結(jié)構(gòu)和進(jìn)程結(jié)構(gòu)會(huì)相互配合地進(jìn)行描述~
Oracle實(shí)例內(nèi)存結(jié)構(gòu)的組成結(jié)構(gòu):

實(shí)例內(nèi)存結(jié)構(gòu)
oracle實(shí)例內(nèi)存結(jié)構(gòu)由兩部分組成SGA(系統(tǒng)全局區(qū))和PGA(用戶全局區(qū))組成,SGA是一塊共享的內(nèi)存區(qū)域,也是***的一塊內(nèi)存區(qū)域;PGA則是用戶會(huì)話專(zhuān)有的內(nèi)存區(qū)域,每個(gè)會(huì)話在服務(wù)器端都有一塊專(zhuān)有的內(nèi)存區(qū)域就是PGA。
SGA組成

篇幅有限,下面對(duì)數(shù)據(jù)庫(kù)緩沖區(qū)、日志緩沖區(qū)、共享池做主要介紹
數(shù)據(jù)庫(kù)緩沖區(qū)緩存

通過(guò)指定 DB_CACHE_SIZE 參數(shù)的值,可以配置緩沖區(qū)高速緩存。緩沖區(qū)高速緩存可存放數(shù)據(jù)文件中塊大小為 DB_BLOCK_SIZE 的數(shù)據(jù)塊的副本。緩沖區(qū)高速緩存是 SGA 的一部分;因此所有用戶都可以共享這些塊。 緩沖區(qū)緩存 是Oracle用來(lái)執(zhí)行sql 的工作區(qū)域,在更新數(shù)據(jù)時(shí),用戶會(huì)話不會(huì)直接去更新磁盤(pán)上的數(shù)據(jù),想想,如果允許這么做,那么頻繁的磁盤(pán)IO對(duì)于系統(tǒng)性能的影響是毀滅性的。所以,實(shí)際的處理流程是這樣的:
select ename,salary from emp where name='阿里巴巴';
首先,當(dāng)用戶提交了該條sql語(yǔ)句,由對(duì)應(yīng)的用戶進(jìn)程(比如我們常用的sql developer)將其發(fā)送給服務(wù)器,監(jiān)聽(tīng)程序監(jiān)聽(tīng)到該條請(qǐng)求,會(huì)為其建立一個(gè)對(duì)應(yīng)的服務(wù)器進(jìn)程,然后服務(wù)器進(jìn)程會(huì)先掃描緩沖區(qū)中有沒(méi)有包含關(guān)鍵行("阿里巴巴")的數(shù)據(jù)塊,如果有,這就算一次緩存***了,然后相關(guān)行會(huì)傳輸?shù)絇GA進(jìn)行進(jìn)一步處理,最終經(jīng)過(guò)格式化后展示給用戶;如果沒(méi)有***,那么服務(wù)器進(jìn)程會(huì)首先將對(duì)應(yīng)行復(fù)制到緩沖區(qū)內(nèi),然后再返回給客戶端。
DML(insert,update,delete)操作同理,加入用戶發(fā)送一條update語(yǔ)句,服務(wù)進(jìn)程依然先去掃描緩沖區(qū),如果緩存***,則直接更新,數(shù)據(jù)變臟;如果沒(méi)有***,由服務(wù)器進(jìn)程將對(duì)應(yīng)數(shù)據(jù)塊先從磁盤(pán)上復(fù)制到緩沖區(qū)內(nèi),再進(jìn)行更新操作。
臟緩沖區(qū)
如果緩沖區(qū)存儲(chǔ)的塊和磁盤(pán)上的塊不一致,該緩沖區(qū)就叫做“臟緩沖區(qū)”,臟緩沖區(qū)最終會(huì)由數(shù)據(jù)庫(kù)寫(xiě)入器(DBWn)寫(xiě)入到磁盤(pán)中去。
數(shù)據(jù)庫(kù)寫(xiě)入器(DBWn)
數(shù)據(jù)庫(kù)寫(xiě)入器是Oracle的一個(gè)后臺(tái)進(jìn)程,所謂后臺(tái)進(jìn)程是相對(duì)于前臺(tái)進(jìn)程(服務(wù)器進(jìn)程)來(lái)講的。DBWn的"n"意味著一個(gè)實(shí)例是可以有多個(gè)數(shù)據(jù)庫(kù)寫(xiě)入器的。
作用:簡(jiǎn)而言之,DBWn的作用就是將變臟了的緩沖區(qū)從數(shù)據(jù)庫(kù)緩沖區(qū)緩存中寫(xiě)入到磁盤(pán)中的數(shù)據(jù)文件中去。
數(shù)據(jù)庫(kù)緩沖區(qū)緩存這塊內(nèi)存區(qū)域和數(shù)據(jù)庫(kù)寫(xiě)入器這塊是比較重要的概念,別的數(shù)據(jù)庫(kù)產(chǎn)品像mySql也都有對(duì)應(yīng)的實(shí)現(xiàn),只不過(guò)叫法不一樣罷了。了解這塊的時(shí)候,要時(shí)刻意識(shí)到會(huì)話是不會(huì)直接更新磁盤(pán)數(shù)據(jù)的,會(huì)話的更新,插入,刪除包括查詢(xún)等都是先作用到緩沖區(qū)上,隨后,DBWn會(huì)將其中的臟緩沖區(qū)轉(zhuǎn)儲(chǔ)到磁盤(pán)上去。
DBWn什么時(shí)候?qū)懭?
DBWn是個(gè)比較懶的進(jìn)程,它會(huì)盡可能少的進(jìn)行寫(xiě)入,在以下四種情況它會(huì)執(zhí)行寫(xiě)入:
a.沒(méi)有任何可用緩沖區(qū)(不得不寫(xiě)啊)
b.臟緩沖區(qū)過(guò)多
c.3秒超時(shí)(最晚3秒會(huì)執(zhí)行一次寫(xiě)入)
d.遇到檢查點(diǎn),即checkPoint(檢查點(diǎn)),檢查點(diǎn)是個(gè)Oracle事件,遇到檢查點(diǎn),DBWn會(huì)執(zhí)行寫(xiě)入。比如實(shí)例有序關(guān)閉的時(shí)候會(huì)有檢查點(diǎn),DBWn會(huì)將所有臟緩沖區(qū)寫(xiě)入到磁盤(pán)上去的,這很容易理解,要保持?jǐn)?shù)據(jù)文件的一致性。
日志緩沖區(qū)

重做日志緩沖區(qū)是一個(gè)循環(huán)緩沖區(qū);服務(wù)器進(jìn)程可以用新條目覆蓋重做日志緩沖區(qū)中已寫(xiě)入磁盤(pán)的條目。LGWR 進(jìn)程的寫(xiě)速度通常都很快,足以確保緩沖區(qū)中始終有存儲(chǔ)新條目的空間。LGWR 進(jìn)程將重做日志緩沖區(qū)寫(xiě)入磁盤(pán)上的活動(dòng)聯(lián)機(jī)重做日志文件(或活動(dòng)組成員)中。LGWR 進(jìn)程將 LGWR 上次寫(xiě)入磁盤(pán)以來(lái)進(jìn)入緩沖區(qū)的所有重做條目復(fù)制到磁盤(pán)。
當(dāng)我們執(zhí)行一些DML操作(insert,update,delete),數(shù)據(jù)塊發(fā)生改變了,產(chǎn)生的變更向量則會(huì)寫(xiě)入到重做日志文件中去。有了這些記錄,當(dāng)系統(tǒng)由于斷電等因素突然宕掉,數(shù)據(jù)庫(kù)緩沖區(qū)緩存內(nèi)的大量臟數(shù)據(jù)還沒(méi)來(lái)得及寫(xiě)入到數(shù)據(jù)文件中去,在重新啟動(dòng)的時(shí)候,會(huì)有一個(gè)實(shí)例恢復(fù)的過(guò)程,在此過(guò)程中就應(yīng)用了重做日志記錄來(lái)使數(shù)據(jù)保持一致;或者數(shù)據(jù)庫(kù)遭遇了物理?yè)p壞,比如磁盤(pán)損壞了,此時(shí)可以通過(guò)Oracle的備份恢復(fù)工具(如RMAN)進(jìn)行數(shù)據(jù)恢復(fù),原理就是 提取備份集-->應(yīng)用重做日志文件中的變更記錄。
日志緩沖區(qū)
日志緩沖區(qū)是一塊比較小的內(nèi)存區(qū)域,它是用來(lái)短期存儲(chǔ)將寫(xiě)入到磁盤(pán)中的重做日志文件中的變更向量的。
日志緩沖區(qū)存在的意義依然是為了減少磁盤(pán)IO,減少用戶的等待時(shí)間,試想下,如果每一次用戶DML操作都要進(jìn)行等待重做記錄被寫(xiě)入到磁盤(pán)中去,體驗(yàn)會(huì)有多差勁。
日志寫(xiě)入器(LGWR)
顧名思義,日志寫(xiě)入器(LGWR)就是把日志緩沖區(qū)內(nèi)的內(nèi)容寫(xiě)入到磁盤(pán)的重做日志文件中去,相比數(shù)據(jù)庫(kù)寫(xiě)入器(DBWn),日志寫(xiě)入器就勤快多了。
以下三種情況LGWR會(huì)執(zhí)行寫(xiě)入:
a.commit時(shí)寫(xiě)入
前面提過(guò),DBWn的寫(xiě)入和commit沒(méi)有任何關(guān)系,如果commit時(shí)數(shù)據(jù)庫(kù)沒(méi)有任何記錄,那數(shù)據(jù)就真的丟失了,Oracle 的重做日志就是為了保證數(shù)據(jù)安全而存在的,commit時(shí),會(huì)話會(huì)先掛起,等待LGWR將這些記錄寫(xiě)入到磁盤(pán)上的重做日志文件中,才會(huì)通知用戶提交完成。所以,LGWR在commit時(shí)執(zhí)行寫(xiě)入,是為了確保事務(wù)永不丟失。
b.日志緩沖區(qū)的占用率達(dá)到1/3。
c.DBWn要寫(xiě)入臟緩沖區(qū)前
共享池

共享池是最復(fù)雜的SGA結(jié)構(gòu),大小通過(guò) SHARED_POOL_SIZE 指定。
常見(jiàn)的幾個(gè)共享池組件:
1.庫(kù)緩存:庫(kù)緩存這塊內(nèi)存區(qū)域會(huì)按已分析的格式緩存最近執(zhí)行的代碼,這樣,同樣的sql代碼多次執(zhí)行的時(shí)候,就不用重復(fù)地去進(jìn)行代碼分析,可以很大程度上提高系統(tǒng)性能。
2.數(shù)據(jù)字典緩存:存儲(chǔ)oracle中的對(duì)象定義(表,視圖,同義詞,索引等數(shù)據(jù)庫(kù)對(duì)象),這樣在分析sql代碼的時(shí)候,就不用頻繁去磁盤(pán)上讀取數(shù)據(jù)字典中的數(shù)據(jù)了
3.PL/SQL區(qū):緩存存儲(chǔ)過(guò)程、函數(shù)、觸發(fā)器等數(shù)據(jù)庫(kù)對(duì)象,這些對(duì)象都存儲(chǔ)在數(shù)據(jù)字典中,通過(guò)將其緩存到內(nèi)存中,可以在重復(fù)調(diào)用的時(shí)候提高性能。
作為DBA,以上內(nèi)容是必須掌握的,如果大家有興趣的話可以多了解下這方面內(nèi)容~