您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Oracle內存結構SGA、PGA、UGA的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
SGA是一組共享內存結構, 被所有的服務和后臺進程所共享。當數據庫實例啟動時,系統全局區內存被自動分配。當數據庫實例關閉時,SGA內存被回收。 SGA是占用內存最大的一個區域,同時也是影響數據庫性能的重要因素。
查詢SGA區的情況:
SQL> show SGA Total System Global Area 3290345472 bytes Fixed Size 2217832 bytes Variable Size 1795164312 bytes Database Buffers 1476395008 bytes Redo Buffers 16568320 bytes SQL> select * from v$sga; NAME VALUE -------------------- ---------- Fixed Size 2217832 Variable Size 1795164312 Database Buffers 1476395008 Redo Buffers 16568320
Fixed Size表示固定區域,存儲SGA各個組件的信息。不能修改大小。
Variable Size表示可變區域,比如共享池、java池、大池等。
Database Buffers表示數據庫高速緩沖區。
Redo Buffers表示日志緩沖區。
固定SGA:顧名思義,是一段不變的內存區,指向SGA中其他部分,Oracle通過它找到SGA中的其他區,可以簡單理解為用于管理的一段內存區。
數據高速緩沖區(Database Buffer Cache):用于存放從數據文件讀取的數據塊,由初始化參數DB_CACHE_SIZE決定。
工作原理和過程是 LRU(最近最少使用 Least Recently Used )。查詢時,Oracle會先把從磁盤讀取的數據放入內存供所有用戶共享,以后再查詢相關數據時不用再次讀取磁盤。插入和更新時,Oracle會先在該區中緩存數據,之后批量寫到硬盤中。通過塊緩沖區,Oracle可以通過內存緩存提高磁盤的I/O性能(注:磁盤I/O的速率是毫米級的,而內存I/O的速率為納秒級)
數據高速緩存塊由許多大小相等的緩存塊組成,這些緩存塊的大小和OS塊大小相同。 這些緩存塊分為3大類
臟緩存塊( Dirty buffers ):臟緩存塊中保存的時被修改過的緩存塊。即當一條SQL語句對某個緩存塊中的數據進行修改后,該緩存塊就被標記為臟緩存塊。最后該臟緩存塊被DBWn進程寫入到硬盤的數據文件中,永久保留起來。
命中緩存塊( Pinned buffers ):命中緩存塊中保存的是最近正在被訪問的緩存塊。它始終被保留中數據高速緩存中,不會被寫入數據文件。
空閑緩存塊(Free buffers):該緩存塊中沒有數據,等待被寫入數據。oracle從數據文件中讀取數據后,尋找空閑緩存塊,以便寫入其中。
Oracle 通過 2 個列表(DIRTY、LRU)來管理緩存塊
1、DIRTY 列表中保存已經被修改但還沒有被寫入到數據文件中的臟緩存塊。
2、LRU列表中保存所有的緩存塊(還沒有被移動到DIRTY列表中的臟緩存塊、空閑緩存塊、命中緩存塊)。當某個緩存塊被訪問后,該緩存塊就被移動到LRU列表的頭部,其他緩存塊就向LRU列表的尾部移動。放在最尾部的緩存塊就最先被移出LRU列表。
數據高速緩存的工作原理過程是:
A、ORACLE在將數據文件中的數據塊復制到數據高速緩存中之前,先在數據高速緩存中找空閑緩存塊,以便容納該數據塊。Oracle 將從LRU列表的尾部開始搜索,直到找到所需的空閑緩存塊為止。
B、如果先搜索到的是臟緩存塊,將該臟緩存塊移動到DIRTY列表中,然后繼續搜索。如果搜索到的是空閑緩存塊,則將數據塊寫入,然后將該緩存塊移動到DIRTY列表的頭部。
C、如果能夠搜索到足夠的空閑緩存塊,就將所有的數據塊寫入到對應的空閑緩存塊中。則搜索寫入過程結束。
D、如果沒有搜索到足夠的空閑緩存塊,則ORACLE就先停止搜索,而是激活DBWn進程,開始將DIRTY列表中的臟緩存塊寫入到數據文件中。
E、已經被寫入到數據文件中的臟緩存塊將變成空閑緩存塊,并被放入到LRU列表中。執行完成這個工作后,再重新開始搜索,直到找到足夠的空閑緩存塊為止。
這里可以看出,如果你的高速緩沖區很小的,不停地寫寫,造成很大I/O開銷。
塊緩沖區可以配置1、2或3個緩沖池,默認只有一個
默認池(Default pool):所有數據默認都在這里緩存,除非你在建表的時候指定 Store(buffer_pool keep) or Store(buffer_pool recycle)。使用LRU算法管理。
保持池(Keep pool):緩存需要多次重用的數據,長期保存內存中,缺省值為0。
回收池(Recycle pool):用來緩存很少重用的數據,用完就釋放,缺省值為0。
原來只有一個默認池,所有數據都在這里緩存。這樣會產生一個問題:大量很少重用的數據會把需重用的數據“擠出”緩沖區,造成磁盤I/O增加,運行速度下降。后來分出了保持池和回收池根據是否經常重用來分別緩存數據。這三部分內存池需要手動確定大小,并且之間沒有共享。例如:保持池中已經滿了,而回收池中還有大量空閑內存,這時回收池的內存不會分配給保持池,這些池一般被視為一種非常精細的低級調優設備,只有所有其他調優手段大多用過之后才應考慮使用。
在9i之前,數據緩沖區的大小是由DB_BLOCK_BUFFER確定,之后的版本中,是由參數DB_CACHE_SIZE及DB_nK_CACHE_SIZE確定。不同的表空間可以使用不同的塊大小,在創建表空間中加入參數BLOCKSIZE指定該表空間數據塊的大小,如果指定的是2k,則對應的緩沖區大小為DB_2K_CACHE_SIZE參數的值,如果指定的是4k,則對應的緩沖區大小為DB_4K_CACHE_SIZE參數的值,以此類推。如果不指定BLOCKSIZE,則默認為參數DB_BLOCK_SIZE的值,對應的緩沖區大小是DB_CACHE_SIZE的值
用于存放日志條目,日志條目就是記錄對數據的改變。當這塊區域用光時,后臺進程LGWR把日志條目寫到磁盤上的聯機日志文件中。它由初始化參數log_buffer決定大小。同樣的道理下,日志緩沖區應該稍微大點,特別是有長時間運行的事務的時候,可以大量減少I/O。
數據寫到重做日志文件之前在這里緩存,在以下情況中觸發:
每隔3秒
緩存達到1MB或1/3滿時
用戶提交時
緩沖區的數據寫入磁盤前
用于存放SQL語句、PL/SQL代碼、數據字典、資源鎖和其他控制信息。它由初始化參數SHARED_POOL_SIZE控制其大小。它包含以下幾個緩沖區:
1、 數據字典緩存(data dictionary cache),用于存儲經常使用的數據字典信息。比如(表的定義、用戶名、口令、權限、數據庫的結構等)。Oracle運行過程中經常訪問該緩存以便解析SQL語句,確定操作的對象是否存在,是否具有權限等。如果不在數據字典緩存中,服務器進程就從保存數據字典信息的數據文件中將其讀入到數據字典緩存中。數據字典緩存中保存的是一條一條的記錄(就像是內存中的數據庫),而其他緩存區中保存的是數據塊信息。
2、 庫緩沖區(Library Cache): 庫緩存的目的就是保存最近解析過的SQL語句、PL/SQL過程和包。這樣一來,Oracle在執行一條SQL語句、一段PL/SQL 過程和包之前,首先在“庫緩存”中搜索,如果查到它們已經解析過了,就利用“庫緩存”中解析結果和執行計劃來執行,而不必重新對它們進行解析,顯著提高執行速度和工作效率。
ORACLE將每一條SQL語句分解為可共享、不可共享的兩部分。
a) 共享SQL區:存儲的是最近執行的SQL語句、解析后的語法樹和優化后的執行計劃。這樣以后執行相同的SQL語句就直接利用在共享SQL區中的緩存信息,不必重復語法解析了。Oracle在執行一條新的SQL語句時,會為它在共享SQL區中分配空間,分配的大小取決于SQL語句的復雜度。如果共享SQL區中沒有空閑空間,就利用LRU算法,釋放被占用的空間。
b) 私用SQL區(共享模式時):存儲的是在執行SQL語句時與每個會話或用戶相關的私有信息。其他會話即使執行相同的SQL語句也不會使用這些信息。比如(綁定變量、環境和會話參數)。
3、 結果高速緩存:結果高速緩存包含 SQL 查詢結果高速緩存和 PL/SQL 函數結果高速緩存。此高速緩存用于存儲 SQL 查詢或 PL/SQL 函數的結果,以加快其將來的執行速度。
4、 鎖與其他控制結構:存儲ORACLE例程內部操作所需的信息。比如(各種鎖、閂、寄存器值)。
大池由初始化參數LARGE_POOL_SIZE確定大小,可以使用ALTER SYSTEM語句來動態改變大池的大小,是可選項,DBA可以根據實際業務需要來決定是否在SGA區中創建大池。如果沒有創建大池,則需要大量內存空間的操作將占用共享池的內存, 將對SHARED POOL造成一定的性能影響,而LARGE POOL是起著這種功能隔離作用的一塊區域。
ORACLE 需要大量內存的操作有:
A、數據庫備份和恢復,如RMAN某些情況下用于磁盤IO緩沖區
B、具有大量排序操作的SQL語句
C、并行化的數據庫操作,存放進程間的消息緩沖區
D、共享服務器模式下UGA在大池中分配(如果設置了大池)
用于支持在數據庫中運行java代碼,一般由java_pool_size控制
加強對流的支持,一般由stream_pool_size控制。流池(或者如果沒有配置流池,則是共享池中至多10%的空間)會用于緩存流進程在數據庫間移動/復制數據時使用的隊列消息
一個PGA是一塊獨占內存區域,Oracle進程以專有的方式用它來存放數據和控制信息。當Oracle進程啟動時,PGA也就由Oracle數據庫創建了。當用戶進程連接到數據庫并創建一個對應的會話時,Oracle服務進程會為這個用戶專門設置一個PGA區,用來存儲這個用戶會話的相關內容。當這個用戶會話終止時,系統會自動釋放這個PGA區所占用的內存。這個PGA區對于數據庫的性能有比較大的影響,特別是對于排序操作的性能。所以,在必要的時候合理管理PGA區,能夠在很大程度上提高數據庫的性能。
程序全局區主要包含排序區、會話區、堆棧區和游標區四個部分的內容,他們各司其職,完成用戶進程與數據庫之間的會話。通常情況下,系統管理員主要關注的是排序區,在必要時需要手工調整這個排序區的大小。另外需要主要的是,游標區是一個動態的區域,在游標打開時創建,關閉時釋放。故在數據庫開發時,不要頻繁的打開和關閉游標可以提高游標操作的效率,改善數據庫的性能。其他分區的內容管理員只需要了解其用途,日常的維護交給數據庫系統來完成即可。
1、 為排序設置合理的排序區大小。
當用戶需要對某些數據進行排序時,數據庫是如何處理的呢?首先,數據庫系統會將需要排序的數據保存到PGA程 序緩存區中的一個排序區內。然后再在這個排序區內對這些數據進行排序。如需要排序的數據有2M,那么排序區內必須至少要有2M的空間來容納這些數據。然后 排序過程中又需要有2M的空間來保存排序后的數據。由于系統從內存中讀取數據比從硬盤中讀取數據的速度要快幾千倍,為此如果這個數據排序與讀取的操作都能 夠在內存中完成,無疑可以在很大程度上提高數據庫排序與訪問的性能。如果這個排序的操作都能夠在內存中完成,顯然這是很理想的。但是如果PGA區 中的排序區容量不夠,不能夠容納排序后的數據,那會如何呢?此時,系統會從硬盤中獲取一個空間,用來保存這需要排序的數據。此時排序的效率就會降低許多。 為此在數據庫管理中,如果發現用戶的很多操作都需要用到排序,那么為用戶設置比較大的排序區,可以提高用戶訪問數據的效率。
在Oracle數據庫中,這個排序區主要用來存放排序操作產生的臨時數據。一般來說,這個排序區的大小占據PGA程序緩存區的大部分空間,這是影響PGA區大小的主要因素。在小型應用中,數據庫管理員可以直接采用其默認的值。但是在一些大型的應用中,或者需要進行大量記錄排序操作的數據庫系統中,管理員可能需要手工調整這個排序區的大小,以提高排序的性能。如果系統管理員需要調整這個排序區大小的話,需要通過初始化參數SORT_AREA_SIZE來實現。為了提高數據訪問與排序的性能,數據庫系統利用內存比硬盤要快幾千倍的事實,會將準備排序的數據臨時存放到這個排序區,并在排序區內完成數據的排序。管理員需要牢記這個原則,并在適當的情況下調整排序區的大小,以提高數據訪問與數據排序的性能。
2、 會話區保存著用戶的權限等重要信息。
在程序緩存區內還包含著一個會話區。雖然絕大部分情況下,管理員不要維護這個會話區,可以讓數據庫系統進行 維護。但是,管理員還是需要了解一下這個會話區的作用。因為這個會話區直接關系著數據庫系統中數據的安全性。數據庫系統不僅是存放數據的一個很好的載體, 而且還提供了一個統一管理數據的平臺,可以根據實際需要,為不同的用戶設置不同的訪問權限。簡單的說,在數據庫中可以控制用戶可以訪問哪些數據,從而提高 數據的安全性。
當用戶進程與數據庫建立會話時,系統會將這個用戶的相關權限查詢出來,然后保存在這個會話區內。如此的話,用戶進程在訪問數據時,系統就會核對 會話區內的用戶權限信息,看看其是否具有相關的訪問權限。由于系統將這個用戶的權限信息存放在內存上,所以其核對用戶權限的速度非常的快。因為系統不用再 去硬盤中讀取數據,直接從內存中讀取。而從內存讀取數據的效率要比硬盤上快幾千倍。
通常情況下,這個會話區內保存了會話所具有的權限、角色、性能統計等信息。這個會話區一般都是由數據庫進行自我維護的,系統管理員不用干預。
3、 堆棧區保存變量信息。
有時候為了提高SQL語句的重用性,會在語句中使用綁定變量。簡單的說,就是SQL語句可以接受用戶傳入的變量。從而用戶只需要輸入不同的變量 值,就可以滿足不同的查詢需求。如現在用戶需要查詢所有員工的信息。然后其又要查詢所有工齡在3年以上的員工等等。此時其實他們采用的是同一個SQL語 句,只是傳遞給系統的變量不同而已。這可以在很大程度上降低數據庫開發的工作量。這個變量在Oracle數據庫系統中就叫做綁定變量。利用綁定變量可以加強與用戶的互動性。另外在這個堆棧區內還保存著會話變量、SQL語句運行時的內存結構等重要的信息。
通常情況下,這個堆棧區跟上面講到的會話區一樣,都可以讓數據庫系統進行自我維護,而管理員不用參與到其中。這些分區的大小,也是系統根據實際情況來進行自動分配的。當這個用戶會話結束時,系統會自動釋放這些區所占用的空間。
4、 游標區。
無論是SQLServer數據庫還是Oracle數據庫中,有時候都需要用到游標技術。當運行使用游標的語句時,Oracle數據庫系統會在程序緩存區中間為其分配一塊區域。這塊區域就叫做游標區。通常情況下,游標用來完成一些比較特殊的功能。而且一般來說,采用游標的語句要比其他語句的執行效率低一點。為此管理員在使用游標的時候,還是需要慎重。
游標區是一個動態的區域。當用戶執行游標語句時,系統就會在這個游標區內創建一個區域。當關閉游標時,這個區域就會被釋放。這創建與釋放,需要 站用一定的系統資源,花費一定的時間。為此在使用游標時,如果頻繁的打開和關閉游標,就會降低語句的執行性能。所以筆者建議,在寫語句時,如果真的有必要 使用游標技術時,則要注意游標不要頻繁的打開和關閉。
另外在Oracle數據庫中,還可以通過限制游標的數量來提高數據庫的性能。如在數據庫系統中有一個初始化參數OPEN_CURSORS。管理員可以根據實際的需要,來設置這個參數,控制用戶能夠同時打開游標的數目。不過需要注意的是,在確實需要才有游標的情況下,如果硬件資源能夠支持的話,那么就需要放寬這個限制。這可以避免用戶進程頻繁的打開和關閉游標。因為頻繁的打開和關閉游標這對游標的操作是不利的,會影響數據庫的性能。
專用服務器模式下,進程和會話是一對一的關系,UGA被包含在PGA中,在聯機服務器模式下,進程和會話是一對多的關系,所以UGA就不再屬于 PGA了,而會在大型池(Large Pool)中分配。但如果從大型池中分配失敗,如大型池太小,或是根本沒有設置大型池,則從共享池(Shared Pool)中分配。
關于“Oracle內存結構SGA、PGA、UGA的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。