我們可以通過show sga命令查看共享池的整體組成部分:
....待截圖....
一、SGA內存結構
Oracle中SGA主要包括:
1、固定數據結構部分(FIXED Size) 2、數據塊緩沖區(DATABASE BUFFER) 3、REDO LOG緩沖區(redo buffers) 4、共享池(在variable size中)。
固定區域包含了所有其他共享內存結構和重要的數據結構的地址和指針、資源、鎖等,可通過如下命令詳細列出具體內容:
select pool,name,bytes from v$segstat where pool = 'shared pool';
顧名思義,共享池是為了讓大家共享數據而設置的緩沖池,而且共享池也是很多會話為自己執行SQL分配共享內存的緩沖池,這些在共享池中分配的內存在會話之間使用十分頻繁,應實現一次分配多次使用,並且能被實例中其他會話共享。
二、SGA內存分配
DB CACHE可以根據數據塊大小很規則的均勻分配,因此不會出現碎片問題,而且DB CACHE分配與歸還相對簡單。但與DB CACHE不同,由於各個會話在共享池中分配空間的時候所需要的空間差異很大,有時幾十字節,有時幾百字節甚至幾兆,因此共享池的分配歸還十分復雜。為了確保共享池中共享數據的訪問性能,共享池的每次內存分配都必須是連續的內存空間,由於這個特點,經過一段時間後,共享池中或多或少都會出現一些碎片,這些碎片分布在一些連續分配的空間之間。
共享池中分配的內存空間有些事永久使用,不釋放的並標記為PERMANENT,這些結構大多是在實例啟動時分配的,也有些是系統運行過程中分配的,但這些內存的特點是只分配,在實例關閉前不會釋放,例如:進程信息數據,會話數據,特殊內容的進程段。進程和會話信息是通過PROCESSES和session參數分配的,實例啟動時一次性分配,分配後不變動,也不會動態擴展,因此加大processes參數必須要重啟實例,另外有些特殊用途的內存數組也是在實例啟動時分配,是動態擴展的,只分配不釋放,在後續可動態擴展,例如:enqueues(locks),enqueue resource,transactions,transaction branches等,對於RAC還有gcs resource,ges resource等。如果這些動態擴展動作經常發生,將會在共享池的連續空間中產生大量的不可釋放的小碎片,從而導致共享池碎片化。(典型案例:9i中經常由於ges resource擴展導致共享碎片問題,並產生4031錯誤。10.2版對此進行了改進,詳細理解請百度)
共享池中還有些是分配後可釋放的,這些內存被標記為freeable或者recreateable。freeable是可以直接釋放,recreateable的內存在unpin後也是可以釋放的,因此他們都是可以重用的內存。
二、共享池管理
共享池內存是通過ORACLE通用內存管理(generic oracle memory manager)來進行管理的,這個就是我們總說的KGH heap manager。在KGH機制下,所有共享池的FREE內存都被掛在稱為freelists的空閒鏈表上,這個空閒鏈表是按照bucket機制建立的,根據空閒內存片段大小,掛在不同的Bucket上,例如:9i的共享池的freelists包含256個bucket,每個bucket上連接了不同大小的空閒內存塊
*小於812B的Bucket是以4B為步長增長的,如16B,20B,24B.....812B;
*超過812B的bucket是以64B為步長增長的,如876B,940B,....4012B;
*超過4012B的bucket是以4096的倍數倍增的,如4108,8042,16396,32784,.....
當某個會話需要從共享池中分配空間的時候,會根據自己分配的大小找到某個bucket,然後找到一個空閒的內存,從中產生的剩余內存,會被掛到相應的bucket上,供其他會話分配使用,而被釋放的內存會被掛到freelists上,為了不碎片化,被釋放的內存自動合並,如果兩個內存片段相鄰,ORACLE會將他們合並為一起。
共享池大小通過shared_pool_size參數定義,自動內存管理模式不用設置此參數,如果設置了此參數那麼共享池會根據這個參數作為初始大小和最小值,無論內存如何調整,共享池大小都不能小於這個參數。
三、共享池內部結構(堆) /*此處很難待續...關注<DBA思想的天空>64頁*/
ORACLE內存空間分配時采用堆管理(HEAP)的模式,堆管理的基礎是KGH。ORACLE常見的內存堆包括SGA HEAP,PGA HEAP,另外大部分表也是堆表(HEAP TABLE),其空間管理的基本概念都是使用KGH。
四、共享池轉儲文件簡單說明
轉儲文件有幾百兆深圳幾個G,共享池的內容轉儲到文件的基本命令,用如下命令可以把LIBRARY_CACHE的內容轉儲到TRACE文件中:
ALTER SESSION SET EVENTS 'immediate trace name LIBRARY_CACHE level <level>';
其中level代表級別,9.2版本後不同level含義如下
* level=1 轉儲庫緩存統計信息
* level=2 轉儲散列表概要
* level=4 轉儲庫緩存對象,只包含基本信息
* level=8 轉儲庫緩存對象,包含詳細信息(包括child reference,pin waiters等)
* level=16 增加堆大小信息
* level=32 增加堆信息