Oracle面試寶典-記憶體結構篇

chenoracle發表於2020-02-28

Oracle 面試寶典 - 記憶體結構篇

 

一:Oracle 記憶體結構由哪幾部分組成?

1   User global area (UGA)

Program global area (PGA)

3   System global area (SGA)

軟體程式碼區Software code areas

二:請分別介紹下UGA PGA SGA 、軟體程式碼區?

1 UGA

UGA 是使用者全域性區,主要存放使用者會話的相關資訊,比如登入資訊。

在會話的生命週期內,UGA 必須對資料庫會話可用。

所以,在連線模式是專用伺服器連線模式時,也就是一個會話對應一個連線,UGA 儲存在 PGA 中。

但是在連線模式是共享伺服器時,也就是多個會話對應一個連線,UGA 儲存在 SGA 中的 large pool ,如果 large pool 空間不夠, UGA 會儲存在 shared pool 。大多情況下都使用專用伺服器連線模式。

2 PGA

PGA(Process Global Area) 程式全域性區, PGA 是一個非共享記憶體區域,它包含 Oracle 程式專用的資料和控制資訊。在 Oracle 程式啟動時建立 PGA 。由每個服務程式和後臺程式專有,所有單個 PGA 的集合就是總例項 PGA 大小。

PGA 內容:

PGA 主要有兩個區域, 私有SQL 區域、 SQL 工作區域。

私有SQL 區域儲存 SQL 的繫結變數值、查詢執行狀態資訊,客戶端程式負責管理私有 SQL 區域。分配的私有 SQL 區域的數量受初始化引數 OPEN_CURSORS 的限制。

SQL 工作區主要用於排序操作、 Hash 連線、點陣圖合併連線時使用的記憶體。

比如 order by group by 等操作。

PGA 管理:

Oracle8i 中, PGA 調整非常複雜,要調整 SORT_AREA_SIZE HASH_AREA_SIZE BITMAP_MERGE_AREA_SIZE CREATE_BITMAP_AREA_SIZE 等引數。在 ORACLE9I 以後,只需要調整 PGA_AGGREGATE_TARGET ,這個值是個軟限制,比如設定大小 2G ,只是一個目標值,實際上 PGA 大小可以超過 2G 。在 12C 開始引入 PGA_AGGREGATE_LIMIT 引數限制 Oracle 例項 PGA 使用記憶體的上限,如果超過限制就採取終止會話的方式來降低 PGA 記憶體的使用量。

3 SGA

系統全域性區域(SGA) ,是一組共享記憶體結構,所有伺服器和後臺程式共享 SGA

Oracle 後臺程式一起構成資料庫例項。

可以在V$SGASTAT 檢視中查詢關於 SGA 元件的資訊。最重要的 SGA 元件如下 :

Database Buffer Cache

Shared Pool

Redo Log Buffer

In-Memory Area

Large Pool

Java Pool

Fixed SGA

•可選的與效能相關的 SGA 子區域

(1)Database Buffer Cache

資料庫緩衝區快取,也稱為緩衝區快取,是資料檔案上的資料塊在記憶體中的副本。主要是為了在記憶體中進行高速的資料查詢和更新, 儘量減少磁碟的 IO 操作。也是 SGA 中佔比比較大的一塊記憶體區域。使用者訪問 DB Cache 的資料比訪問磁碟上的資料速度更快數 ( 記憶體的讀取效率是磁碟讀取效率約 14000 ) ,因此應用系統應該儘可能多地從 DB Cache 中訪問資料。在大多數情況下, DB Cache 的命中率越高,訪問效能就越好。

緩衝池包括:default 預設池、 keep 保留池、 recycle 回收池

Buffer Cache 管理:

通過三條連結串列進行管理:HASH 連結串列、檢查點佇列連結串列、 LRU 連結串列

HASH 連結串列

HASH 連結串列的作用是通過 HASH 演算法 ( 消耗 CPU 資源 ) ,提高 DB Cache 中資料塊的定位速度。也就是邏輯讀。

比如,根據需要訪問塊的塊號、檔案號計算HASH 值,在通過 HASH 值找到對應的 HASH Bucket, 搜尋 Buckect 後的連結串列,找到目標 BH(Buffer Header), 通過 BH 找到 BA(Buffer Address) ,按照 BA 訪問具體的 Buffer, 這個就是邏輯讀的過程。

檢查點佇列連結串列(CKPT-Q)

主要用於記錄髒塊。

Buffer Cache 其實就是磁碟資料檔案的快取,以修改塊的操作為例,如 update ,只是修改 Buffer Cache 中的 Buffer, 修改完成後 ,update 操作就算完工了。這樣 Buffer 中的資料和磁碟中的 block 就不一致了,這樣的 Buffer 就是髒 Buffer ,髒塊由 DBWR 程式統一寫磁碟,但是 Buffer Cache 通常很大,有幾萬或幾十萬 Bufeer ,怎麼在 Buffer Cache 中找到哪些是髒 Buffer 呢,這就需要一個連結串列,將所有髒 Buffer 都串起來, DBWR 寫髒塊時,就是按照這個串起來的連結串列的順序來寫,這樣的髒連結串列有兩個,一個是 LRUW ,另一個是 CKPT-Q。 buffer cache 中,修改完資料後,會將對應的資料塊加入到檢查點佇列 (CKPT-Q)

LRU 連結串列 ( 最近最少使用連結串列 )

物理讀時,伺服器程式將資料塊從資料檔案讀進Buffer Cache 中,假如 Buffer Cache 10000 Buffer ,那麼程式應該覆蓋哪個 Buffer 呢?

簡單說,就是程式將資料塊讀進Buffer Cache 的什麼地方。

答案是,覆蓋最不常用的Buffer LRU 主要就是解決如何快速找到最不常用的 Buffer

Oracle 8i 之前, LRU 演算法 DB Cache LRU 上是會移動的,常用的緩衝會被換到 LRU 的熱端,不常用的緩衝會被擠到 LRU 的冷端,一般來說會話分配 Cache 時,會從 LRU 的冷端開始查詢。這種 LRU 演算法會產生效能瓶頸

Oracle 8i 開始, LRU 的演算法有所改進, LRU 鏈上的緩衝不再需要移動了,而是通過 tch 計數器大小值來判斷某個資料塊是否為熱塊。

(2)Redo Log Buffer

重做日誌緩衝區是SGA 中的一個迴圈緩衝區,它儲存描述資料庫更改的重做條目。

重做記錄是一種資料結構,它包含重做DML DDL 操作對資料庫所做更改所需的資訊。資料庫恢復將重做項應用於資料檔案以重構丟失的更改。

LGWR 按順序將資料塊寫入磁碟,而 DBW 將資料塊分散寫入磁碟。分散寫比順序寫要慢得多。因為 LGWR 允許使用者避免等待 DBW 完成緩慢的寫操作,所以資料庫提供了更好的效能。

LOG_BUFFER 初始化引數指定 Oracle 資料庫在緩衝重做條目時使用的記憶體量。與其他 SGA 元件不同,重做日誌緩衝區和固定 SGA 緩衝區不會將記憶體分成顆粒。

(3)Shared Pool

相比於Buffer Cache ,共享池中的內容可謂是雜亂無章。 Oracle 基本上將不能放進 Buffer Cache 中的資料都扔進了共享池,使得共享池的分配和釋放極為頻繁。

共享池中最基本的記憶體分配單元成為Chunk, 相當於 Buffer Cache 中的 Buffer 或塊的概念。

Chunk 的大小極不統一,最新的 Chunk 可以只有十來個位元組,最大的 Chunk 有幾十兆甚至幾百兆。基本記憶體單元大小的不統一,再加上頻繁進行分配、釋放操作,使共享池中極易產生記憶體碎片。總的來說,共享池是 Oracle 中最複雜的記憶體池。

包括以下內容:

•Library Cache

•Data Dictionary Cache

•Server Result Cache

•Reserved Pool

1 Library Cache

庫快取 主要 儲存 使用者提交的 SQL 語句、SQL 語句相關解析數、 SQL 執行計劃、 PL/SQL 程式塊等

2 Data Dictionary Cache

dictionary cache 裡存放了資料字典的記憶體結構,包括 表的定義、Storage 資訊、使用者許可權資訊、約束定義、表的統計資訊等。 SQL 語句解析期間頻繁地訪問資料字典。構造 dictionary cache 的目的是為了加快 SQL解析過程中語義解析 的速度。

資料字典快取也被稱為行快取(Row Cache ),因為它是以記錄行為單元儲存資料的,而不像 Buffer Cache 是以資料塊為單元儲存資料。

3 Server Result Cache

伺服器結果快取是共享池中的記憶體池。與緩衝池不同,伺服器結果快取儲存結果集,而不是資料塊。

執行查詢時,資料庫將確定查詢結果是否存在於查詢結果快取中, 如果結果存在,那麼資料庫將從快取中檢索它,而不是執行查詢。快取使資料庫能夠避免重新讀取資料塊和重新計算結果的昂貴操作。

4 Reserved Pool

保留池是共享池中的一個記憶體區域,Oracle 資料庫可以使用它來分配大的連續記憶體塊。

如果Oracle 解析一個 PL/SQL 程式單元,也需要從共享池中分配記憶體給這些程式單元物件。由於這些物件本一般比較大(如包),所以分配的記憶體空間也相對較大。系統經過長時間執行後,共享池可能存在大量記憶體碎片,導致無法滿足對於大塊記憶體段的分配。為了使有足夠空間快取大程式塊, Oracle 專門從共享池內建出一塊區域來來分配記憶體保持這些大塊。

資料庫以塊的形式從共享池分配記憶體。分塊允許將大物件( 超過 5 KB) 載入到快取中,而不需要單個連續區域。通過這種方式,資料庫減少了記憶體碎片的產生。

(4)Large Pool

大池是一個可選的記憶體區域,用於比共享池更大的記憶體分配。

大池可以為以下情況提供大記憶體分配:

用於共享伺服器和 Oracle XA 介面 ( 用於事務與多個資料庫互動 )

並行執行中使用的訊息緩衝區

用於恢復管理器 (RMAN) I/O 從屬的緩衝區

(5)Java Pool

Java 池是儲存 Java 虛擬機器 (JVM) 中所有特定於會話的 Java 程式碼和資料的記憶體區域。此記憶體包括在呼叫結束時遷移到 Java 會話空間的 Java 物件。

對於專用伺服器連線,Java 池包括每個 Java 類的共享部分,包括方法和只讀記憶體 ( 如程式碼向量 ) ,但不包括每個會話的 Java 狀態。

(6) 可選的與效能相關的SGA 子區域

一些SGA 子區域只針對特定的效能特性啟用。本節包含以下主題 :

In-Memory Area

Memoptimize Pool

In-Memory 12C 開始,在 SGA 中新增加的記憶體區域,可以實現表資料按列儲存;

In-Memory 並沒有取代傳統的 Buffer Cache ,二者並存在 SGA 中。列式儲存在訪問多行、少列情況下效能更優。

memoptimize pool 大小通過MEMOPTIMIZE_POOL_SIZE 設定,其中儲存著啟用了 fast lookup 表的雜湊索引。

18c 開始支援 Memoptimized Rowstore ,可用於提高查詢效能。針對頻繁基於主鍵查詢的 SQL 語句的效能提高十分明顯。可以通過 CREATE TABLE ALTER TABLE MEMOPTIMIZE FOR READ 語句來啟用表的 fast lookup

(7)軟體程式碼區概述

軟體程式碼區是儲存正在執行或可以執行的程式碼的記憶體的一部分。Oracle 資料庫程式碼儲存在一個軟體區域中,這個軟體區域通常比使用者程式的位置更具排他性和受保護性。 軟體區域的大小通常是靜態的,只有在軟體更新或重新安裝時才會改變。這些區域所需的大小因作業系統而異。

軟體區域是隻讀的,可以安裝共享的,也可以安裝非共享的。有些資料庫工具和實用程式( Oracle Forms SQL*Plus) 可以安裝為共享的,但有些則不能。在可能的情況下,資料庫程式碼是共享的,這樣所有使用者都可以訪問它,而不需要在記憶體中有多個副本,從而減少了主記憶體,並在總體上提高了效能。如果在同一臺計算機上執行,資料庫的多個例項可以將相同的資料庫程式碼區域用於不同的資料庫。

歡迎關注我的微信公眾號"IT小Chen",共同學習,共同成長!!!

Oracle面試寶典-記憶體結構篇

Oracle面試寶典-記憶體結構篇



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29785807/viewspace-2677717/,如需轉載,請註明出處,否則將追究法律責任。

相關文章