- Oracle DBA基礎教程
- 林樹澤
- 4669字
- 2021-03-26 13:21:39
2.4 Oracle數據庫內存結構
Oracle的內存結構由兩大部分組成,一個是SGA,另一個是PGA。PGA稱為程序全局區,程序全局區不是實例的一部分,當服務器進程啟動時,才分配PGA。而SGA稱為系統全局區,它是數據庫實例的一部分,當數據庫實例啟動時,會首先分配系統全局區,在系統全局區中包含幾個重要的內存區,即數據庫高速緩存(Database buffer cache)、重做日志緩存(Redo log buffer cache)、共享池(Shared pool)、大池(Large pool)和Java池(Java pool)。接下來的幾個小節中將詳細介紹Oracle數據庫的內存結構。
2.4.1 共享池(shared pool)
Oracle引入共享池的目的就是共享SQL或PL/SQL代碼,即把解析得到的SQL代碼的結果在這里緩存,其中PL/SQL代碼不僅在這里緩存,同時也在這里共享。共享池由兩部分組成(如圖2-5所示),即庫高速緩存和數據字典高速緩存。

圖2-5 共享池的組成
1.庫高速緩存
庫高速緩存存儲了最近使用過的SQL和PL/SQL語句。當然它的容量是有限的,Oracle采用一種LRU(least recently used)算法管理庫高速緩存,該算法的基本思想是把一段時間內沒有被使用過的語句清除,一旦緩沖區填滿,算法把最近最少使用的執行計劃和解析樹從庫高速緩存中清除。顯然庫高速緩存設置得越大,就可以共享的SQL或PL/SQL代碼就越多,但是Oracle并沒有設計直接設置庫高速緩存的指令,只能通過設置共享池的大小間接地更改,而共享池是SGA的一部分,所以共享池不能超過SGA的大小,如下面例子所示設置共享池大小。
例子2-2 設置共享池的大小
SQL> alter system set shared_pool_size = 16M; 系統已更改。 通過例子2.3驗證修改結果。
例子2-3 查看共享池的大小
SQL> show parameter shared_pool_size; NAME TYPE VALUE ------------------------------------ ----------- --------------------------------------- shared_pool_size big integer 16777216
2.數據字典高速緩存
顧名思義,該緩存區是與數據字典相關的一段緩沖區。在數據字典高速緩沖區中存儲了數據文件、表、索引、列、用戶、權限信息和其他一些數據庫對象的定義。在SQL語句的解析階段,數據庫服務器需要這些信息來解析用戶名和用戶的訪問權限。如果Oracle緩存了這些信息,無疑相應地提高了查詢時間。
數據字典緩存也稱為字典緩存或者行緩存,無論稱呼如何,它的作用就是把相關的數據字典信息放入緩存以提高查詢的響應時間。
同樣數據字典高速緩存的大小取決于共享池尺寸的大小。如果設置的太小,當查詢需要數據字典信息時,Oracle將通過不斷地訪問數據字典表來獲得所需的信息,由于數據字典也是存儲在磁盤上的一類數據文件,頻繁的磁盤I/O無疑降低了數據庫的查詢速度。如果需要設置字典高速緩存的大小,需要通過設置shared_pool_size間接實現。
2.4.2 數據庫高速緩沖區(database buffer cache)
數據庫高速緩沖中存儲了最近從數據文件讀入的數據塊信息或用戶更改后需要寫回數據庫的數據信息,此時這些沒有提交給數據庫的更改后的數據稱為臟數據。當用戶執行查詢語句,如select * from dept時,如果用戶查詢的數據塊在數據庫高速緩存中,Oracle就不必從磁盤讀取,而可以直接從數據庫高速緩存中讀取,顯然物理讀取的速度比從內存讀取的速度慢很多,這些緩存的數據由LRU算法管理。可見Oracle設計各種緩存的目的基本相同,就是提高查詢速度,減少用戶的查詢響應時間。Oracle使用LRU算法管理庫緩沖區,把最近沒被使用的數據庫從庫高速緩存中刪除,為其他的查詢數據塊保留空間。
Oracle使用參數DB_BLOCK_SIZE和DB_BLOCK_BUFFERS設置庫高速緩存的大小,DB_BLOCK_SIZE是Oracle數據塊的大小,而DB_BLOCK_BUFFERS是數據庫的個數,二者的乘積就是庫高速緩存的大小。例子2-4為查詢Oracle數據塊的大小。
例子2-4 查看數據塊大小
SQL> show parameter db_block_size; NAME TYPE VALUE --------------------------------------------------------- ------------------- -------------- db_block_size integer 8192
注意
用這種方式設置數據庫高速緩存的大小需要重啟數據庫才能生效,db_block_size的值是8192字節(即8K字節)。
在Oracle9i及以上版本中提供了一個DB_CACHE_SIZE參數來設置Oracle數據庫高速緩存區的大小,該參數可以動態更改,之后可以通過查詢指令查看更改后的參數。
接下來用例子2-5說明查詢Oracle11g中數據庫高速緩存的大小。
例子2-5 查詢數據庫高速緩存的大小
SQL> show parameter db_cache_size; NAME TYPE VALUE -------------------------------------------------------- ------------------- ----------------- db_cache_size big integer 0
因為在Oracle11g中,SGA為數據庫服務器自動管理,所以該參數值為0,當然在運行Oracle11g數據庫時,數據庫高速緩存一定是已分配好的,我們使用show sga指令查看數據庫高速緩沖區分配的內存大小,如例子2-6所示。
例子2-6 查詢數據庫高速緩存的大小
SQL> show sga; Total System Global Area 535662592 bytes Fixed Size 1334380 bytes Variable Size 260047764 bytes Database Buffers 268435456 bytes Redo Buffers 5844992 bytes
說明
上述指令查詢SGA的分配情況,其中Database Buffers為數據庫緩存區的大小。我們更改的值為32M,而顯示的值為33554432字節,二者一致,說明修改成功(32M=32*1024*1024bytes=33554432 bytes)。
雖然在Oracle11g中數據庫高速緩存的大小自動管理,但是用戶可以設置該數據庫組件的大小,如例子2-7所示。
例子2-7 動態設置數據庫高速緩沖區大小
SQL> alter system set db_cache_size = 200M; 系統已更改。
在Oracle中引入了Buffer Cache Advisory Parameter參數,其目的是讓Oracle對于數據庫緩沖區的內存分配提供一些建議。
下面介紹緩沖區顧問參數(Buffer Cache Advisory Parameter)的作用,緩沖區顧問用于啟動或關閉統計信息,這些信息用于預測不同緩沖區大小導致的不同行為特性。對于DBA可以參考這些統計信息,基于當前的數據庫工作負載,設置優化的數據庫高速緩存。
緩存顧問通過初始化參數DB_CACHE_ADVICE啟動或關閉顧問功能,該參數有以下三個狀態。
● OFF:關閉緩存顧問,不分配緩存顧問的工作內存。
● ON:打開緩存顧問,分配工作內存。
● READY:打開緩存顧問,但不分配緩存顧問的工作內存。
例子2-8 當前緩存顧問的狀態
NAME TYPE VALUE -------------------------------------------------------- ------------------ ----------------- db_cache_advice string ON
在上述輸出中可以看出,參數db_cache_advice的值為ON,所以默認是打開緩存顧問的。例子2-9演示了如何設置緩存顧問為關閉狀態,其實就是通過設置參數db_cache_advice實現的。
例子2-9 關閉數據庫高速緩存顧問
SQL> alter system set db_cache_advice = off; 系統已更改。
在更改了緩存顧問狀態后,通過例子2-10查看當前的緩存顧問狀態,以驗證更改結果。
例子2-10 查看數據庫高速緩存顧問狀態
SQL> show parameter db_cache_advice; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_cache_advice string OFF
當然我們的目的是使用緩存顧問,所以需要再次將參數db_cache_advice的值設置為ON,如下例所示。
SQL> alter system set db_cache_advice = on; 系統已更改。
在設置顧問緩存為開啟狀態后,Oracle開始統計與設置數據庫緩存相關的建議信息,可以通過動態性能視圖v$DB_CACHE_ADVICE查看緩沖區的建議信息,如例子2-11所示。
例子2-11 查看與設置數據庫高速緩沖區相關的信息
SQL> col id for 99 SQL> SELECT id, name, block_size, size_for_estimate, buffers_for_estimate 2 FROM v$db_cache_advice; ID NAME BLOCK_SIZE ADV SIZE_FOR_ESTIMATE BUFFERS_FOR_ESTIMATE -- ---------------- -------------------- ---------- --- ----------------- ---------------------------------------- 3 DEFAULT 4096 ON 3.0703 786 3 DEFAULT 4096 ON 6.1406 1572 3 DEFAULT 4096 ON 9.2109 2358 3 DEFAULT 4096 ON 12.2813 3144 3 DEFAULT 4096 ON 15.3516 3930 3 DEFAULT 4096 ON 18.4219 4716 3 DEFAULT 4096 ON 21.4922 5502 3 DEFAULT 4096 ON 24.5625 6288 3 DEFAULT 4096 ON 27.6328 7074 3 DEFAULT 4096 ON 30.7031 7860 3 DEFAULT 4096 ON 33.7734 8646 ID NAME BLOCK_SIZE ADV SIZE_FOR_ESTIMATE BUFFERS_FOR_ESTIMATE -- ---------------- -------------------- ---------- --- ---------------------- ---------------------------------------- 3 DEFAULT 4096 ON 36.8438 9432 3 DEFAULT 4096 ON 39.9141 10218 3 DEFAULT 4096 ON 42.9844 11004 3 DEFAULT 4096 ON 46.0547 11790 3 DEFAULT 4096 ON 49.125 12576 3 DEFAULT 4096 ON 52.1953 13362 3 DEFAULT 4096 ON 55.2656 14148 3 DEFAULT 4096 ON 58.3359 14934 3 DEFAULT 4096 ON 61.4063 15720 已選擇20行。
2.4.3 重做日志高速緩沖區(redo buffer cache)
當用戶執行了如INSERT、UPDATE、DELETE、CREATE、ALTER和DROP操作后,數據會發生變化,這些變化了的數據在寫入數據庫高速緩存之前會先寫入重做日志緩沖區,同時變化之前的數據也放入重做日志高速緩存,這樣在數據恢復時Oracle就知道哪些需要前滾哪些需要后滾。
重做日志緩沖區的大小是可以動態調節的,即在數據庫運行期間修改這塊內存的大小,Oracle提供了一個初始化參數LOG_BUFFER,在數據庫實例啟動時就分配好重做日志緩沖區的尺寸。例子2-12演示了如何查看重做日志緩存區。
例子2-12 查看重做日志緩存區
SQL> show parameter log_buffer; NAME TYPE VALUE -------------------------------------------------------- ------------------- -------------
說明
重做日志緩存區參數log_buffer是靜態參數,不能動態修改。如果嘗試修改,會提示如下錯誤。
log_buffer integer 5653504 SQL> alter system set log_buffer = 1M; alter system set log_buffer = 1M * ERROR 位于第 1 行: ORA-02095: 無法修改指定的初始化參數
2.4.4 大池(large pool)和Java池
大池是SGA的一段可選內存區,只在共享服務器環境中配置大池(large pool)。在共享服務器環境下,Oracle在共享池中分配額外的空間用于存儲用戶進程和服務器進程之間的會話信息,但是用戶進程區域UGA(可理解為PGA在共享服務器中的另一個稱呼)的大部分將在大池中分配,這樣就減輕了共享池的負擔。在大規模輸入、輸出及備份過程中也需要大池作為緩存空間。
Oracle提高了參數large_pool_size設置大池的尺寸。下面使用例子2-13查看大池的尺寸。
例子2-13 查看大池大小
SQL> show parameter large_pool_size NAME TYPE VALUE --------------------------------------------------------- ------------------ ------------ large_pool_size big integer 52M
參數large_pool_size是動態參數,可以通過alter system指令修改該參數的值,語句格式為:
“alter system set large_pool_size = 48M;”。
Java池也是可選的一段內存區,但是在安裝Java或者使用Java程序時,則必須設置Java池,它用于編譯Java語言編寫的指令。Java語言與PL/SQL語言在數據庫中有相同的存儲方式。Oracle提供了參數Java_pool_size設置Java池的大小。使用例子2-14查看當前Java池的大小。
例子2-14 查看Java池的大小
SQL> show parameter java_pool_size; NAME TYPE VALUE ---------------------------------------------------- ------------- java_pool_size big integer 0
說明
在Oracle11g中,Java池大小由數據庫服務器在SGA中自動分配,當然用戶也可以使用alter system指令修改該參數的值,在例子2.14中參數Java_pool_size的值為0,說明該參數為自動管理。
2.4.5 流池(Streaming pool)
流池也稱為流內存,它是為Oracle流專用的內存池,流(Stream)是Oracle數據庫中的一個數據共享,其大小可以通過參數stream_pool_size動態調整。
2.4.6 PGA(進程全局區)和UGA(用戶全局區)
進程全局區(PGA)是服務器進程專用的一塊內存,它是操作系統進程專用的內存,系統中的其他進程是無法訪問這塊內存的。PGA獨立于SGA,PGA不會在SGA中出現,它是由操作系統在本地分配的。
1.PGA(進程全局區)
PGA中存儲了服務器進程或單獨的后臺進程的數據信息和控制信息。它隨著服務器進程的創建而被分配內存,隨著進程的終止而釋放內存。PGA與SGA不同,它不是一個共享區域,而是服務器進程專有的區域。在專有服務器(與共享服務器相對的概念)配置中包括如下的組件:
● 排序區:對某些的SQL語句執行結果進行排序。
● 會話信息:包含本次會話的用戶權限和性能統計信息。
● 游標狀態:標明當前會話執行的SQL語句的處理階段。
● 堆棧區:包含其他的會話變量。
注意
在共享服務器配置中,多個用戶進程共享一個服務器進程,上述的一些內存區可能在SGA中分配。如果創建了大池(large pool),這些內存結構就存儲在大池中,否則它們存儲在共享池中。
圖2-6和圖2-7分別是專有服務器模式和共享服務器模式下的PGA結構圖。

圖2-6 專有服務器模式下的PGA結構

圖2-7 共享服務器模式下的PGA結構
注意
在共享服務器結構中,會話信息是存儲在SGA中的,兩種模式下堆棧區(Stack space)都存儲在PGA中。
2.UGA(用戶全局區)
在共享服務器模式下有一個重要的概念,即UGA(用戶全局區),它表示用戶的會話狀態,這部分內存會話總可以訪問,UGA存儲在每個共享服務器都可以訪問的SGA中,這樣任何服務器都可以使用用戶會話的數據和其他信息。而在專有服務器模式下,用戶會話狀態不需要共享,用戶進程與服務器進程是一一對應的關系,所以UGA總是在PGA中分配。
3.PGA內存管理
從Oracle9i開始,Oracle提供了兩種方法管理PGA,即手動PGA管理和自動PGA管理。采用手動管理時,必須告訴Oracle一個特定的進程需要的排序區,允許使用多少內存。而在自動PGA管理中,則要求高速Oracle在系統范圍內可以為PGA中的特定功能(如排序區)分配多少內存。例子2-15顯示了筆者計算機上PGA中排序區的大小。
例子2-15 查詢PGA中排序區的大小
SQL> show parameter sort_area_size; NAME TYPE VALUE --------------------------------------------------------- ------------------ ---------------- sort_area_size integer 65536
在服務器進程最初查詢時,會使用512KB內存實現數據排序,在Oracle將排序數據處理完之前,數據排序區的大小就由參數SORT_AREA_SIZE決定。
注意
在Oracle10g和Oracle11g中可以實現共享服務器連接時PGA的自動管理,而在Oracle9i中,使用共享服務器連接時,只能使用手動PGA管理。
2.4.7 如何獲得內存緩沖區的信息
SGA是Oracle中所有進程共享的一段內存區,其中共享了數據庫信息,如數據庫高速緩沖區中的數據、共享池中的庫、高速緩存中的SQL語句等。了解這些內存緩沖區的大小有助于理解Oracle的內存分配情況。例子2-16為查看數據庫的SGA(系統全局區)。
例子2-16 查看SGA中內存的分配情況
SQL> show sga; Total System Global Area 535662592 bytes Fixed Size 1334380 bytes Variable Size 260047764 bytes Database Buffers 268435456 bytes Redo Buffers 5844992 bytes
在上述輸出中可以看到,SGA、Database Buffers和Redo Buffers 的尺寸,前面已經講解了這些內存組件的作用。讀者或許注意到了Fixed Size和Variable Size這兩個參數,它們和兩個內存區有關,下面解釋這兩個內存區。
● 和fixed size相關的內存區:在固定的SGA中,存儲一組指向SGA中其他組件的變量。它的大小因平臺不同而有差異,用戶無法控制,但通常固定SGA 區很小。Oracle使用這個內存區來尋找其他SGA區,可以理解為數據庫的自舉區。
● 和Variable Size相關的內存區:該部分內存區包括共享池、Java池和大池,其中Variable Size的尺寸要高于上述三個內存結構之和,因為在Total SGA中除去的db_cache_size部分也包括在Variable Size中。
同時讀者也可以參照例子2-17查詢當前數據庫的SGA尺寸。
例子2-17 查看SGA的尺寸
SQL> show parameter sga_max_size; NAME TYPE VALUE ------------------------------------------------------ --------------------- ------------------ sga_max_size big integer 512M
說明
在Oracle11g中該參數的值得到修正而以M字節作為單位,更利于識別,而在Oracle10g版本中參數sga_max_size的值以字節為單位。
- Android Jetpack開發:原理解析與應用實戰
- C#完全自學教程
- 構建移動網站與APP:HTML 5移動開發入門與實戰(跨平臺移動開發叢書)
- Android 9 Development Cookbook(Third Edition)
- R的極客理想:工具篇
- Oracle JDeveloper 11gR2 Cookbook
- Java Web程序設計任務教程
- Java編程的邏輯
- 深入剖析Java虛擬機:源碼剖析與實例詳解(基礎卷)
- Oracle GoldenGate 12c Implementer's Guide
- Arduino計算機視覺編程
- UML2面向對象分析與設計(第2版)
- Julia數據科學應用
- 嵌入式C編程實戰
- JavaEE架構與程序設計