標籤:
記憶體結構
現代電腦中,CPU 對記憶體的訪問速度要比從磁碟的速度快千倍,因此 Oracle 對於資料的訪問 也盡量都在記憶體中完成,而不是直接修改硬碟上的資料。記憶體內容在合適的時候再同步到磁碟。 Oracle 利用記憶體來克服磁碟 IO的束縛,在記憶體中進行活動越多,系統效能越好,反之,在磁碟上進 行的操作越多,系統效能越差。(原文地址:http://blog.sunansheng.com/2016/04/29/oracle-memory/)
Oracle 是一個記憶體消耗大戶,它消耗的記憶體可以分成兩部分——進程共用部分和進程專有部分。 這裡的進程專指Oracle 進程(Server Process 和Background Process),進程共用部分就叫做 SGA (Shared Global Area ),進程專有部分就叫做 PGA (Program Global Area)。
對於不同類型的應用系統,這兩個部分的意義也不同。對於OLTP系統,其特徵大量的小事務, SGA 要比PGA更為重要。對於OLAP 系統來說,其特徵是大資料量的關聯,因此PGA 要比SGA 對系統的影響更大。因為PGA 直接決定了大的排序、雜湊操作效率。
1.SGA
SGA 是一大塊記憶體的總稱,其內部分成若干組成部分,是一個典型的 SGA ,每 個部分都有獨特的作用。
2.Data Buffer Cache
由Server Process 從磁碟讀入的資料就放在這塊記憶體中。而修改資料時,也是在這個地區中對數 據進行修改。Data Buffer Cache 中會同時保留資料庫被修改前(Before Image,前鏡像)和被修改後 (After Image ,後鏡像)的拷貝。
Data Buffer Cache 中的記憶體可以被分成 3 類:
- Free Buffers:指那些不包含任何資料的記憶體,這些記憶體可以用來裝載以後讀入的資料。
- Dirty Buffer:這部分包含被修改過的,但是還沒有寫到磁碟上的資料區塊。
- Pinned Buffer:正在被使用者使用的記憶體。
當使用者進程請求資料時,Oracle 首先查看資料是否已經在 Data Buffer Cache 中,如果資料已在 Data Buffer Cache 中,則 Server Process不必再訪問磁碟,直接從 SGA 中讀取資料就可以了。如果 資料還沒有載入到SGA ,Server Process就必須從磁碟讀入資料,但是在讀入之前,Server Process 必須保證Data Buffer Cache 中有足夠的 Free Buffer 來容納這些資料,如果Server Process在掃描一 定數量的Buffer 後還沒有找到Free Buffer ,它就會通知DBWn 進程把Dirty Buffer寫到磁碟上,一 旦些完成,原先這些Dirty Buffer 就變成 Free Buffer ,就可以重用了。
究竟把哪些個Dirty Buffer 寫到磁碟?這就會用到LRU(Least Recently Used)演算法了,這種算 法確保最近越少被使用的資料區塊,越先被寫到磁碟,空間越先被釋放。這種演算法是基於這樣一個假 設:“越近被用到的資料,就越有可能被再次用到”。在 Data Buffer Cache 中,不僅有一個 LRU List 存在,而是同時使用多個 LRU List ,如 Free Buffer 、Dirty Buffer 、Pinned Buffer 都是使用LRU演算法。
(1)按照用途不同的多個 Buffer Cache。
大部分情況下資料庫有一個預設的Buffer Cache放置所有的資料就足夠了,不過 Oracle 允許通 過多個Buffer Cache進行微調。
資料庫中的不同資料的訪問頻率是不一樣的,像使用者屬性、商品列表這種字典型資料可能需要 經常使用,因此這類資料應該儘可能久的放在 Buffer Cache中,而一些日誌型資料只會偶爾採用到, 這類資料就應該儘快地從Buffer Cache中移走,以釋放空間。對於符合這種特點的應用來說,Oracle 提供了其他兩種Buffer Cache——Keep Buffer Pool和Recycle Buffer Pool,再加上預設的 Buffer Cache 就有3 種Buffer Pool 了。這 3 種的區別在於對其中資料的保留原則,Keep就是保留得盡量久,而 Recycle就是儘快釋放,如表所示。
| Buffer Pool 名稱 |
初始化參數 |
說 明 |
| Keep Buffer Pool |
DB_KEEP_CACHE_SIZE |
這個地區內的資料會儘可能久地保留在記憶體中。 對於那些體積較小、訪問頻繁的表,比如使用者屬 性表,可以考慮放在這個Cache 中,以提高訪問 速度 |
| Recycle Buffer Pool |
DB_RECYCLE_CACHE_SIZE |
放在這個地區中的資料一用完就會被移出。對於 那些體積巨大、偶爾使用的日誌表,可以考慮放 在這個記憶體中,以儘快釋放記憶體 |
| Default Buffer Pool |
DB_CACHE_SIZE |
預設的Cache |
(2 )按照資料區塊大小的多個 Buffer Pool 。
除了按照保留時間劃分Buffer Cache,Oracle 還可以按照資料區塊的大小分配多個 Buffer Cache。 Oracle 10g 中允許建立不同資料區塊大小的資料表空間,DBA 在建立資料庫時需要使用的 DB_BLOCK_SIZE 參數,這個參數決定的是資料庫標準資料區塊大小,以後建立的資料表空間預設會繼承 這個塊大小。但是DBA也可以用其他資料區塊大小建立資料表空間,最多可以使用5 種不同資料區塊大小 (2KB 、4KB 、8KB 、16KB、32KB),這些資料表空間叫做非標準資料區塊大小的資料表空間。要想在一個資料 庫內同時使用多種資料區塊大小,一個重要的條件就是必須要配置對應的非標準Buffer Cache。對應 參數是DB_nK_CACHE_SIZE。
之前提到的Keep Buffer Pool、Recycle Buffer Pool都只用於標準資料區塊。而Default Buffer Pool 則是由所有的標準和非標準Buffer Pool 組和在一起的。所謂標準、非標準是根據建立資料庫時指定 的DB_BLOCK_SIZE 而言的,如果這個值是2KB ,那麼其他的4KB 、8KB 、16KB、32KB 就叫做 非標準資料區塊。如果定義成 32KB,那麼 2KB 、4KB 、8KB 、16KB 就叫做非標準資料區塊。
3.Shared Pool
Shared Pool是SGA 中另一個非常重要的地區,尤其對於OLTP系統來說,Shared Pool配置對 於系統效能的意義尤為重要。和 Data Buffer Cache 存放的是使用者資料不同,Shared Pool 中存放的是 代碼,包括PL/SQL 代碼、SQL 陳述式以及資料字典資訊。Shared Pool又可以分成 Library Cache 和 Dictionary Cache兩個地區。
如果使用者有過其他語言的開發經驗,一定知道編譯過程,也就是要把使用者代碼轉換成機器語言,比如Java 語言要把*.java 檔案編譯成.class 檔案。資料庫也是一樣,使用者提交的無論是用 PL/SQL 編 寫的預存程序或者純粹的SQL 代碼,這些代碼都是基於人類語言編寫的,要想電腦能夠執行這些 代碼,首先要把它們編譯成 CPU 可識別的機器代碼,這個過程就是編譯。而編譯產生的機器代碼就 儲存在Library Cache 中,Shared Pool 是一個所有使用者可以共用的地區,這樣就可以獲得兩個好處: 首先,使用者如果再次執行同一段代碼時,就可以省掉解析過程,直接重用先前產生的機器代碼;其 次,如果其他使用者執行相同代碼,也能夠重用,減少解析。
一個SQL 陳述式完整執行過程可以分成 4 個階段:
(1) 解析。
在這個階段,要進行語義、文法分析、許可權檢查,包括語句是否拼字正確、是否有語法錯誤、 資料庫是否有a 這個對象、使用者是否有 a 的存取權限等。
這些檢查通過後,再檢查這個語句之前是否已經解析過了。Oracle 對每個語句都會計算出雜湊 值,用這個值在Shared Pool 中查看是否有對應的執行計畫。如果有,就說明這個語句曾經執行過, 已有的執行計畫拿過來就可以使用,而不再需要執行下面的(2 )、(3)步(這也就是只進行軟解析 Soft Parse);如果沒有,則必須(1 )、(2 )、(3 )步都執行完後才能產生執行計畫(也就是所謂的 Hard Parse)。
(2 )最佳化。
這個階段根據對象的統計資訊、當前選擇的最佳化器模式(CBO/RBO)來確定最佳訪問路徑。所 謂對象的統計資訊,比如一個表裡面有多少條記錄、每條記錄平均長度、佔據多少個資料區塊、索引 的高度等。這些資訊記錄在系統字典中,比如user_tables.num_rows 。
另外一個影響最佳化的因素是“最佳化器模式”(Optimizer Mode )。這個配置是告訴 Oracle 希望如 何返回記錄,比如 first_rows_n代表儘快返回頭 n 條記錄;all_rows 代表著儘快返回整個記錄集,而 不關心頭幾條的返回速度。模式不同會產生不同的執行計畫。
根據這兩類資訊,Oracle 的最佳化起引擎會產生多個訪問路徑,如全表掃描、索引掃描、Nest Loop Join 或Hash Join 等,Oracle 會計算每種訪問路徑的成本,把成本最小的訪問路徑作為最佳路徑。
(3 )產生執行計畫。
這一階段根據上一階段產生的最小成本的訪問路徑,產生最終的執行計畫。
(4 )返回查詢結果。
依據上一步的執行計畫,訪問資料獲得結果集,返回給使用者。如果是DML語句,而修改資料 並返回結果。
前3 個階段是資源密集型操作,包括 CPU 、Latch、Lock各種資源,對於系統效能影響比較明 顯。而Shared Pool 的目的就是為了減少前 3 個階段的活動。
Library Cache 中存放的代碼部分,Dictionary Cache中存放的資料字典資訊。在解析階段,解析 器要判段表名、列名是否正確、使用者是否有許可權執行請求的操作,這些資訊就是資料字典,包括在 接下來的最佳化階段,CBO產生執行計畫所用到的對象統計資料都來自於資料字典。如果這些資料不 在記憶體中,Oracle 就需要從資料字典把這些資料讀入 Dictionary Cache。資料字典在 Dictionary Cache 緩衝的越多、保留時間越長,解析時間越短,系統效能越好。
4.Redo Log Buffer
Redo Log Buffer 使用來儲存Redo 記錄,和 Buffer Cahce、Shared Pool 比起來,這個地區空間 非常小,通常只有幾MB。當一個Server Process 改變 Data Buffer Cache 中的資料時(DML操作), 就會產生Redo記錄,這些記錄儲存在 Redo Log Buffer 中。LGWR 進程負責把Redo Log Buffer 中的 內容寫到磁碟上的Redo Log File 中。
Redo Log Buffer是採用迴圈方式工作的,一旦LGWR 進程把日誌內容寫到磁碟,LGWR 就可 以覆蓋這塊內容。LGWR 通常是系統中最繁忙的進程,Oracle 提供了一種 Nologging技術可以跳過 Redo Log產生,從而減少 LGWR 的負載,不過這個技術只是在有限的幾種場合有用,比如直接數 據載入。
5.Large Pool 、Java Pool、Stream Pool
這幾個記憶體組件相對來說就不是很重要了,Large Pool 最主要的用途就是供 RMAN 備份和共用 串連模式。Java Pool 用於支援 JAVA 虛擬機器(JVM ),Stream Pool 用於支援流。
6.SGA自動管理
在Oracle 10g之前的版本中,SGA 各個組件的調整也是 DBA的日常工作之一。從 Oracle 10g開 始,這個地區能夠自動調整了,這個特性是Oracle 自動管理功能的一部分,使用者只需要設定一個新增 的參數 SGA_TARGET就可以實現 SGA 的自動調整。SGA 自動調整見後面章節。
PGA
對於每個服務進程、後台進程,Oracle 都會為其分配一個 PGA ,這塊記憶體地區用於儲存每個用 戶的私人資料。和SGA 的共用不同,PGA 是排他使用的。PGA 可以分成兩部分。
Private SQL Area:這塊地區用於儲存 SQL 綁定變數資訊,雖然 SQL 陳述式的執行計畫可以 共用,但是每個使用者的綁定變數資訊卻要儲存在 PGA 中;OPEN_CRUSRO 定義的就是在 這塊地區中,使用者保留的 Cursor 數量。
Runtime Area:每當 Session 執行一個語句時分配的空間,這塊空間可以用於資料排序、 Hash、串連等,當語句執行完畢後,這塊地區就被 Oracle 釋放了。
為了減少使用者等待時間,加快響應速度,Oracle 會盡量在記憶體中完成排序、Hash、串連等操作, 這塊記憶體就是PGA 的Runtime Area 中。如果操作能夠在記憶體中完成,不需要磁碟IO,這種操作就 叫做Optimal Mode Operation。否則,如果不能在記憶體中完成,就會把部分中間資料先轉移到磁碟上, 這種操作就叫做One(Multiple)-Pass(一路或多路)Operation。磁碟操作會降低系統效能。因此 PGA 大小和效能有密切關係。這些記憶體地區通過 SORT_AREA_SIZE、HASH_AREA_SIZE、 BITMAP_AREA_SIZE 定義。
Oracle 9i 開始引入了 PGA 的自動管理,通過把WORKAREA_SIZE_POLICY設定為AUTO 來 啟用PGA 自動管理,如果這個參數設定成 MANUAL,就退回到手動管理。自動管理只需要定義一 個參數PGA_AGGREGATE_TRAGET 就好了。PGA 自動管理對於記憶體使用量效率更高,比如如果使 用手動管理,那麼每個會話分配的 PGA 不會自動歸還給系統,無論會話是否執行操作還是 IDLE 狀 態,都必須在使用者退出後(Log Off)PGA 空間才會歸還給系統,這就可能造成大量記憶體被閑置,而 真正需要工作的會話有無法獲得足夠的PGA ,而自動管理中,一旦會話執行的操作結束,使用的 Runtime-Area 就會自動歸還給作業系統。
[精]Oracle 記憶體結構詳解