詳解Oracle實例內存結構和進程結構
由于內存結構和進程結構關系較緊密,進程會作用到對應的內存區域,比如數據庫寫入器作用到數據庫緩沖區緩存中,日志寫入器會作用到日志緩沖區,所以在這里我把內存結構和進程結構會相互配合地進行描述~
Oracle實例內存結構的組成結構:

實例內存結構
oracle實例內存結構由兩部分組成SGA(系統全局區)和PGA(用戶全局區)組成,SGA是一塊共享的內存區域,也是***的一塊內存區域;PGA則是用戶會話專有的內存區域,每個會話在服務器端都有一塊專有的內存區域就是PGA。
SGA組成

篇幅有限,下面對數據庫緩沖區、日志緩沖區、共享池做主要介紹
數據庫緩沖區緩存

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

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

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