作為一個複雜的Oracle資料庫系統來說,每時每刻都要處理不同使用者所提交的SQL語句,擷取資料並返回資料給使用者。前面已經說到,解析SQL語句的工作是在Oracle執行個體中的shared pool所完成的。那麼對於每個session來說,其執行SQL語句時所傳入的綁定變數放在哪裡?而且,對於那些需要執行比較複雜SQL的session來說,比如需要進行排序(sort)或hash串連(hash-join)時,這時,這些session所需要的記憶體空間又從哪裡來?另外,還有與每個session相關的一些管理控制資訊又放在哪裡?對於諸如此類與每個session相關的一些記憶體的分配問題,Oracle通過引入PGA這個記憶體組件來進行解決。
1、PGA的概念及其包含的記憶體結構
PGA按照Oracle官方文檔解釋,叫做程式全域區(Program Global Area),但也有些資料上說還可以理解為進程全域區(Process Global Area)。這兩者沒有本質的區別,它首先是一個記憶體地區,其次,該地區中包含了與某個特定伺服器處理序相關的資料和控制資訊。每個進程都具有自己私人的PGA區,這也就意味著,這塊地區只能被其所屬的進程進入,而不能被其他進程訪問,所以在PGA中不需要latch這樣的記憶體結構來保護其中的資訊。
籠統地說,PGA裡包含了當前進程所使用的有關作業系統資源的資訊(比如開啟的檔案控制代碼等)以及一些與當前進程相關的一些私人的狀態資訊。每個PGA區都包含以下兩部分。
固定PGA部分(Fixed PGA):這部分包含一些小的固定尺寸的變數,以及指向變化PGA部分的指標。
變化PGA部分(Variable PGA):這部分是按照堆(Heap)來進行組織的,所以這部分也叫做PGA堆。PGA堆中所包含的記憶體結構包括:
有關一些固定表的非揮發性記憶體。
如果session使用的是專用連線方式(dedicated server),則還含有使用者全域區(User Global Area,UGA)子堆。如果session使用的是共用串連方式(shared server),則UGA位於SGA中。UGA是PGA中的最重要的部分。
調用全域區(Call Global Area,CGA)子堆。
UGA是包含與某個特定session相關資訊的記憶體地區,比如session的登入資訊以及session私人的SQL地區等。每個UGA也包含以下兩個部分。
查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/
固定UGA部分(Fixed UGA):這部分包含一些小的固定尺寸的變數,以及指向變化UGA部分的指標。
變化UGA部分(Variable UGA):這部分也是按照堆來進行組織的,可以從X$KSMUP視圖中看到有關UGA堆的分布情況。UGA堆的分布與open_cursors、open_links等參數有關係。所謂的遊標(cursor)就是放在這裡的,遊標指向shared pool裡的包含SQL文本以及執行計畫等的對象。UGA堆中所包含的記憶體結構介紹如下。
私人SQL地區(Private SQL Area):這部分地區包含綁定變數資訊以及運行時的記憶體結構等資料。每一個發出SQL語句的session都有自己的私人SQL地區。這部分地區又可分成以下兩部分。
永久記憶體地區:這裡存放了相同SQL語句多次執行時都需要的一些遊標資訊,比如綁定變數資訊、資料類型轉換資訊等。這部分記憶體只有在遊標被關閉時才會被釋放。
運行時地區:在處理SQL語句時的第一步就是要建立運行時地區,這裡存放了當SQL語句運行時所使用的一些資訊。對於DML(INSERT、UPDATE、DELETE)語句來說,SQL語句執行完畢就釋放該地區;而對於查詢語句(SELECT)來說,則是在所有資料行都被擷取並傳遞給使用者以後被釋放,或者該查詢被取消以後也會被釋放。
Session相關的資訊。這部分資訊包括以下幾部分。
正在使用的包(package)的狀態資訊。
使用alter session這樣的命令所啟用的跟蹤資訊,或者所修改的session層級的最佳化器參數(optimizer_mode)、排序參數(sort_area_size等)、修改的NLS參數等。
所開啟的db links。
可使用的角色(roles)等。
工作區(Work area):這塊地區主要用來存放執行SQL的過程中所產生的中間資料,比如排序時,需要在這裡存放排序過程中的中間資料。這部分佔據了PGA中的大部分空間。其大小依賴於所要處理的SQL語句的複雜程度而定。如果SQL語句包含諸如group by、hash-join等這樣的操作,則會需要很大的SQL工作區域。實際上,我們調整PGA也就是調整這塊地區。
而UGA所處的位置完全由session串連的方式決定:
如果session是通過共用伺服器(shared server)方式登入到資料庫的,則毫無疑問,UGA必須能夠被所有進程訪問,所以在這種情況下,UGA是從SGA中進行分配的。進一步說,如果SGA中設定了large pool,則UGA從large pool裡進行分配;否則,如果沒有設定large pool,則UGA只能從shared pool裡進行分配。
如果session是通過專用伺服器(dedicated server)方式登入到資料庫的,則UGA是從進程的PGA中進行分配的。