探索系列——神人steve adams之著oracle8i interal service(二十)

wisdomone1發表於2010-05-11
the reserved list
           自從oracle7.3引入paged pl/sql程式碼塊時,大量的共享池記憶體大塊大小低於5000 bytes.到這種程式以至於,在一個成熟的例項中查詢或搜尋共享池空閒
列表和lru lists為了得到大於這個size的chunks,基本上是futile無效果的.因此,oracle不會這樣作.
           相反,oracle會為巨大的大塊保留部分共享池.這個保留區域的大小預設是共享池的5%,當然也可以用shared_pool_reserved_size來調節.

           大於5000bytes的大塊會放置在共享池的reserved part.這個門限可由_shared_pool_reserved_min_alloc來控制,但不能改變.微小或細小的大塊不會放入the
reserved pool,巨大的大塊不會放入或歸入共享池的其它部分,除非是在例項啟動期間.
 

           共享池的reserved part上面的空閒記憶體不包含在一般共享池自由列表中,會有一個單獨的reserved自由列表來管理這個.但是,共享池對於unpinned recreatable
chunks沒有自己的lru lists.但是,當為了一般的自由列表freeing記憶體時,巨大的大塊不會flushed,當為了reserved free list freeing memory,細小的大塊不會flushed.
   
            在v$shared_pool_reserved檢視reserved pool統計資訊.特別是,request_misses列顯示從reserved 自由列表中請求一個巨大的大塊不能立馬滿足的次數.這個
度量值應是0,也就是說在共享池的reserved part有足夠的空閒記憶體來滿足短暫freeable memory的需要,不用flush unpinned recreatable chunks(這些大塊否則會長期進行快取)


            你可以配置你的監控軟體來檢視v$shared_pool_reserved的used_space列,確定共享池reserved part的大小是否合適.





marking objects for keeping
            在一個大小定義適度的共享池情況下,僵死的大塊dead chunks將會flush out.但是,任何flushing也可能導致一些有價值的物件同時也被flushed out.特別是間歇使用的
重建物件,但是它們再次重建成本很高的,因為它們很巨大,需要複雜的處理過程.可能你不想緩衝的一些序列被flushed out,因為這導致餘下的一些快取序列不能被使用.

            當然,減輕這種風險辦法之一,就是在共享池中用dbms_shared_pool.keep標記一些有價值的物件.從而把這些物件以及次級物件立馬放入library cache中,標記它們為keeping.
這樣操作應儘可能在例項啟動後直接作完,以最小化共享池碎片形成.


             有時可能錯誤認為或斷言,一些如包的大物件沒必要標記為keeping,因為它們會放置在共享池的reserved part,因為不可能會被flushed out.但是大多數
大物件實際上是以多個不同的small chunks載入入共享池的,所以從它們的大小來講它們沒有得到專門特別的保護.

             根據使用的高頻率來防止一些物件從共享池中age out也不明智之舉.如果共享池定義合理well sized,在業務高峰時the lru lists會相當短,unpinned objects將會非常快速
age out,除非你標記它們為keeping.
            
             keeping也應用於保護重複執行的cursors,或者再次執行,再不管它們的大小.



             為了完整或從全域性考慮,我也提及x$ksmlru可以幫你確認其它kept的library cache objects.x$ksmlru記錄需要flushes的最多10個共享池大塊分配的統計資訊.但是,並不是所有的
chunk allocation可以抓獲.事實上,只有最大的分配會被抓獲.另一方面,無論何時你查詢它時,最不尋常或不常見的資訊會完全清除掉,所以你不能偶爾或隨意查詢(也就是你要有計劃地查詢x$ksmlru)













flushing the shared pool
         合併共享池中的連續空閒的大塊,唯一方法就是,透過alter system flush shared_pool來flush 共享池.問題在於到底作還是不作,dba對此有不同的意見分歧.

         實際上,flushing共享池可以減輕shared pool latch競爭,極大減少ora-04031,不會馬上產生大家通常認為對於效能的影響(或者講沒有哪種強的影響),特別是一些
重要或關鍵物件標記為keeping.另一方面,如果所有的關鍵物件標記為keeping,而且你的共享池沒有過度定義大小,你很少或基本不用flush 共享池,除非你的例項very demanding,
長期uptime需要.

         我個人更傾向flush 共享在夜間(backup後),如果平時或其它時間共享池的空閒空間變得很不足或者碎片過多.但是,你可能也要確保flushing 共享池不會leave
快取序列的unwanted不必要或空閒的gaps.這可以透過標記序列為keeping或者臨時unloading 序列用alter sequence nocache.









heaps and subheaps
          你可能發現共享池的x$表是以ksm或者kgh開頭.它們分別是oracle memory manager和heap manager modules的名字.
memory manager負責與os互動以獲得oracle所用的記憶體,以及記憶體的靜態分配.動態記憶體管理是由heap manager來實現.這也就是為何共享叫作sga heap.

          一個heap是由一個heap描述符和一個或多個記憶體extents組成.一個heap也可能包含許多subheaps.這種情況下,heap描述符和subheap的extents在
parent heap是以chunks方式顯現.heap描述符大小是與heap型別有關,它包含heap的自由列表和lru lists的列表頭list headers.一個extent就是一個指向前面
和下一個extents的小型指標頭,它的記憶體其它部分用於動態分配的heap(and the rest of its memory is available to the heap for dynamic allocation).


         除了reserved list特徵,共享池中的subheaps的結構與共享池本身一模一樣.記憶體是以chunks方式進行分配.空閒大塊根據它們的大小是以自由列表方
式進行組織.另外unpinned 重建大塊是以兩種lru lists(週期重複和瞬間的大塊)來分別組織的.subheaps甚至具有一個包含備用空閒記憶體的一個主要固定記憶體大塊.
subheaps也可能包含subheaps,巢狀層次可達4層之多.


         理解掌握subheaps非常重要,因為快取在共享池中的大多物件實際上是駐存於subheaps上面,而不是top-level heap最頂端的heap.在一個subheap中查詢一個新的
大塊空間更像是在共享池中查詢一個新的大塊空間,除了subheaps的增長是以分配一個新的extents來進行的,但是共享池的extents個數是固定的.給subheaps分配新的extents
是由一個最小的extent size來控制的,因此可能在一個subheap中查詢一個small chunk會失敗,因為沒有一個parent heaps能分配一個必需要的最小的extent sizes的一個大塊
出來.










the large pool
         如果配置了large_pool_size,large pool配置為sga可變區域中一個獨立的heap存在.large pool不是shared pool一部分,它是受large pool latch保護.large pool
僅僅包含空閒和freeable大塊.它不包含任何重建的大塊,因此不會使用heap manager的lru機制.

         為了防止large pool出現碎片,所有的large pool chunks四捨五入為_large_pool_min_alloc,預設是16k.此引數不應調節.它不會影響某些大塊是否在大池中分配.相反,
如果配置了大池,會根據用途在大池中分配大塊,如有必要會四捨五入為必需的大小.

         如果你使用如下的一些oracle特徵,請使用大池:
             mts(多執行緒伺服器)或oracle*xa
             rman
             並行查詢選項pqo





process memory
         除了sga之外,每個oracle程式也使用三個同樣或類似的全域性區域:
                the process global area(pga)
                the user global area(uga)
                the call global area(cga)


        許多dba不清楚pga與uga之間的區別.這個區別簡單就似一個程式與一個會話一般.雖然程式與會話之間一般是
一對一的關係,它也可能更為複雜.最明顯的例子就是mts配置,它就是多個會話對應程式的關係.這種配置,往往是
每個程式有一個pga,每個會話一個uga.pga包含任何時侯程式可能服務且與某個會話無關的一些資訊,然而uga卻包含
某個特定會話的資訊.




the pga
        駐存於程式私有或專有記憶體上,而非共享記憶體中.從某種意義上講pga就是一個全域性區域,它包含oracle伺服器程式碼可以訪問到的全域性變數和資料結構.
但是,它不能在多個程式間共享.每個oracle伺服器程式有一個自己的pga,它包含與程式相關的資訊.由於其它程式不能訪問它們,故pga中的結構不需要用latches.

        pga包含程式正在使用一些os資源資訊,以及程式的狀態資訊.

        pga包含兩個component組成區域areas,固定pga與可變pga,或者pga heap.固定pga serves a similar purpose to the fixed sga(我譯為:固定sga起著和
固定sga類似或同樣的用途).它在大小上固定,包含數以百計的原子變數,細小的資料結構,指定可變sga的指標.


        可變pga是一個heap.它的大塊對於x$ksmpp的程式process均是可見的visible,它的結構與x$ksmsp一樣.pga heap包含
一些固定表的固定記憶體,這個固定記憶體與一些初始化引數有關.這些引數包括:db_files,log_files(oracle8.1之前),以及control_files.除此之外,pga heap基本
上全部專用於dedicated to它的subheaps,主要是uga(如何在應用的話)和cga.
 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9240380/viewspace-662429/,如需轉載,請註明出處,否則將追究法律責任。

相關文章