王文娟,王潤中
(1.廣州南洋理工職業學院,廣州510900;2.Northern Alberta Institute of Technology,加拿大)
以Oracle 數據庫產品享譽全球的Oracle 公司,在2013 年后成為繼Microsoft 后全球第二大軟件公司,而其中的數據庫產品Oracle 11g,又以其自動內存管理被認為是內存走向智能化的重要管理階段,是數據庫軟件發展的一個里程碑。Oracle 從可占OS 系統內存的1/3 到1/2,直到占用80%的內存,如此高占比物理內存促使我們有必要在校企合作實訓實驗中探討Oracle 的內存管理。根據工作負載情況,通過對SGA 和PGA 監測,在多種內存管理方式下選擇不同的內存管理方式并進行各種參數進行設置,并充分利用其智能化內存管理特性,使得數據庫性能達到最優。
在裝有Oracle 數據庫的計算機上,其內存主要由SGA、PGA 和UGA 組成,如圖1 所示,通常講的Oracle的內存管理,主要是對SGA 和PGA 這兩部分區域進行管理。
當Oracle 啟動時,首先使用的是靜態內存管理,此時的內存是按照SGA 內預先配置好參數進行內在分配;當實例啟動時,Oracle 會自動分配SGA,當關閉例程時,Oracle 會自動釋放SGA 所占用的空間;PGA 是在服務器進程啟動或創建時分配,并為服務器進程所專用;UGA 則是為用戶進程存儲會話狀態的。

圖1 Oracle內存結構
自動管理模式是在Oracle 9i 開始引入的,先是PGA 自動管理,SGA 仍為手動管理;在10g 時Oracle 推出了ASMM,實現了SGA 和PGA 內部結構的自調節,即PGA 和SGA 均為自動管理;進入11g 之后,自動內存管理AMM 實現對SGA 和PGA 的規劃全部統籌,因而AMM 成為數據庫發展中的重要部分,這種對PGA和SGA 統一進行自動管理,從某種程度上來說內存管理逐漸的走向智能化。
SGA(System Global Area)是用于加載數據、對象并保存運行狀態和數據庫控制信息的一塊內存區域,在數據庫實例啟動時進行分配,大小通常SGA 與操作系統、內存大小、CPU、同時登錄的用戶數有關;在數據庫運行過程中,內存大小可以在線修改與自動配置,這便是動態內存管理。
SGA 是一個共享的內存結構,每個實例都有自己的SGA 區。當多個用戶并發地連接到同一個實例后,這些用戶將共享此實例SGA 中的數據。圖2 是SGA的基本內存結構,除了數據高速緩沖區(Data Buffer Cache)、重做日志緩沖區(Redo Log Buffer)、共享池(Shared Pool)、Java 池(Java Pool)、大型池(Large Pool)外,還包括三個子緩沖區:保留緩沖區、循環緩沖區和非標準大小塊緩沖區。

圖2 SGA內存結構
Oracle 支持動態SGA 特性,無需關閉實例,在無DBA 的干預的情況下,根據系統上的工作負載,就可以自動調整數據高速緩沖區、共享池和大型池的大小。池可以進行擴展也可以進行縮小,前者是為滿足自身增長需求,后者則是滿足其他池的擴展需求。
Oracle 從Oracle 9i 開始支持動態SGA 特性。ASMM(Automatic Shared Memory Management)的主要工作是讓DBA 不再需要手工設置shared pool、buffer pool 等若干內存池的大小,而AMM 的引入,則使得Oracle 內存管理更加靈活多樣,組合出來有5 種內存管理形式,即自動內存管理,自動共享內存管理,手工共享內存管理,自動PGA(Program Global Area)管理,手動PGA 管理方式。單擊“自動內存管理”禁用按鈕,并選擇“啟用自動共享內存管理”,DBA 可以在此頁中使數據庫自動設置下的各SGA 組件的內存達到最佳分配方式。如此實現AMM 和ASMM 的切換,從而實現內存多種管理方式,具體內存管理方式設置見表1 內存管理方式設置表。
如果指定了MEMORY_TARGET 沒有指定MEMORY_MAX_TARGET,重啟后MEMORY_MAX_TARGET=MEMORY_TARGET。如果指定了MEMORY_MAX_TARGET 而沒有指定MEMORY_TARGET,重啟后MEMORY_TARGET 為0。

表1 內存管理方式設置表
Oracle 10g 引入sga_target,可以自動對SGA 進行調整,且SGA 的總大小不能超過初始化參數SGA_MAX_SIZE 的設置,具體命令如下:
SQL>ALTERSYSTEMSETSGA_MAX_SIZE=***MSCOPE=SPFILE;
SQL>ALTER SYSTEM SET SGA_TARGET=***MSCOPE=SPFILE;
Oracle 11g 則對這SGA 和PGA 兩部分進行綜合,引入memory_target,可以自動調整所有的內存,即自動內存管理。11g 里面引入了兩個成對的新參數——memory_target 和memory_max_target,這兩個參數讓SGA 和PGA 在總的內存量內靈活自動調整,在默認情況下,sga_target 和pga_aggreargate,target 設置為零,也就是說采用了新的自動調整參數方式。MEMORY_TARGET 可被動態調整,但要注意不可超過MEMORY_MAX_TARGET 的值。
注意,當處在ASMM 狀態時,設置SGA 各部分內存參數的最小值限制;在處在AMM 狀態時,若此時的數據庫使用了SPFILE,由于數據庫關閉后,系統會將上一次數據庫關閉時的內存分配狀態記錄下來,建議使用SPFILE。具體命令如下:
SQL>ALTER SYSTEM SET MEMORY_MAX_TARGET=***M SCOPE=SPFILE;
從一般意義上講SGA 越大系統的性能越好,但這兩個參數不宜設置過高,不應超過系統實際內存的1/2,否則在實例啟動時可能會出現錯誤。
與多個進程共享的SGA 相反,PGA(Program Global Area)是只為一個用戶進程服務的,其作用是保護會話信息、排序信息以及用戶的私有數據信息。只有該用戶的服務進程能夠訪問它自己的PGA 區。當用戶進程連接到Oracle 數據庫時,創建一個會話并通過C語言的運行時調用malloc()或memmap()來分配內存,會話結束時,PGA 被釋放。
對于這種只有操作系統進程或線程專用的內存,PGA 包含了工作區(SQL Work Areas)、會話區(Session Memory)和私有SQL 區,而SQL Work Areas 又由sort area、hash area、bitmap merge area 組成如圖3 所示。

圖3 PGA內存結構
這些組件分工各有不同,Session Memory 主要存儲一些登錄的信息。Private SQL Area 分為永久區域(Persistent Area)和時區域(Runtime Area)。永久區域存儲綁定變量等信息,在游標關閉時釋放;運行時區域存放了SQL 語句運行時的信息,如執行查詢的狀態信息、查詢工作區(SQL Work Areas)等。不過對于共享服務器模式,Session 這部分內存在SGA 中分配。
PGA 分兩種管理模式,一是手動PGA 內存管理,用于為用戶指定排序區和散列區所使用的內存,且每個連接使用相同的內存。二是自動PGA 內存管理,即只設置Oracle 可以使用的PGA 的總量,由Oracle 根據系統負載決定具體分配,可以動態擴大也可以回收。
根據表1,在11g 中要進行手動內存管理時,先關閉自動內存管理AMM,然后才能設置PGA 具體命令如下:
SQL>ALTER SYSTEM SET MEMORY_TARGET=0;
若PGA 設為自動內存管理,PGA_AGGREGATE_TARGET 設置為非0 值,具體命令如下:
SQL>ALTER SYSTEM SET PGA_AGGREGATE_TARGET=***M;
如果設置workarea_size_policy 為auto 則sort_area_size,hash_area_size 等參數不用被忽略;如果workarea_size_policy 為manual,則進行sort_area_size,hash_area_size 等參數設置生效。
我們可以對圖2 所示的SGA 的各個組件均可進行監測,可以根據監測的情況調整各個組件參數的值,也可以直接根據工作任務進行配置。
在進行聯機事務處理時,對于物理內存16GB,根據Oracle 官方提供的使用經驗,一般Oracle 所占物理內存的80%分配給SGA,只給PGA 內存設置20%,命令如下:
SQL>ALTER SYSTEM SET SGA_MAX_SIZE=10g SCOPE=SPFILE;
SQL>ALTER SYSTEM SET SGA_TARGET=10g SCOPE=SPFILE;
SQL>ALTER SYSTEM SET WORKAREA_SIZE_POLICY=AUTO SCOPE=BOYH;
SQL>ALTER SYSTEM SET PGA_AGGREGATE_TARGET=2000M SCOPE=BOYH;
但是通過對內存監測,最后師生們普遍認為SGA與PGA 的總和不宜超過總內存的70%。
我們要做備份,需要使用大型池,此時數據緩沖區沒有大量的數據,在自動內存管理模式下,自動將縮小數據緩沖區并抽調該內存為大型池服務。
不過,此時SGA 中的有些池不受動態大小調整的影響,例如非標準塊大小的緩沖池,以及KEEP 池或RECYCLE 池的非默認塊大小。再有,就是日志緩沖區、數據高速緩沖區同樣可以不受內存調整的影響。
在手工管理方式下,做備份一般對大型池設置較大一些,具體命令如下:
SQL>ALTER SYSTEM SET LARGE_POOL_SIZE=128M;
數據緩沖區用于緩存從數據文件中檢索出來的數據塊,它與查詢效率和更新數據的性能緊密相關,通過使用如下命令查看情況:
SQL>SHOW PARAMETER db_cache_size;
如果db_cache_size 顯示為0,這并不意味著Oracle 沒有給實例分配了數據庫高速緩沖區,而是在SGA在自動管理模式。使用以下命令查看命中率:
SQL>select 1-((physical.value-direct.value-lobs.value)/logical.value)
2"Buffer Cache Hit Ratio"
3 from v$sysstat physical,v$sysstat direct,v$sysstat lobs,v$sysstatlogical
4 where physical.name='physical reads'
5 anddirect.name='physical reads direct'
6 andlobs.name='physical reads direct(lob)'
7 andlogical.name='session logical reads';
如果此時顯示命中率低于90%,要適度調整db_cache_size 的大小,命令下:
SQL>ALTER SYSTEM SET db_cache-size=1120M;