怎麼樣管理Oracle的內存

怎麼樣管理Oracle的內存

1、管理共享池
共享池的管理一直也是頗有爭議的一個話題,每個版本不一樣,具體管理方式也大不一樣(關鍵是算法不一樣,結構還是基本一樣)。共享池的內部管理方式,我們可以通過如下的dump來分析:
SQL> alter session set events 'immediate trace name heapdump level 2';
通過分析跟蹤文件,其實可以發現,在8i/9i的管理中,都是通過extent、bucket與chunk來管理共享池。在物理空間管理上,共享池劃分爲多個extent,每個extent中包含很多對應的chunk。在空閒空間的管理上,則採用freelist的方式管理,8i共有11(0-10)個bucket空閒列表,而9i則有255(0-254)個bucket空閒列表,每個bucket管理的chunk的大小不一樣,當申請空間時,則到對應的bucket去申請空閒的chunk,如果沒有,則轉到下一個bucket,分裂一個大的chunk爲已用的chunk與另外一個小的空閒chunk,放到對應的空閒bucket中。
如果我們想清理共享池,可以採用如下的命令:
SQL>alter system flush shared_pool

而共享池中,我們比較關心的則是library cache的管理,因爲這部分是進行語句分析與cache的重要部分。我們可以用如下的命令來dump library cache:
SQL> alter session set events 'immediate trace name LIBRARY_CACHE level LL';
其中LL代表Level級別,對於9.2.0及以後版本,不同Level含義如下:
Level =1 ,轉儲Library cache統計信息
Level =2 ,轉儲hash table概要
Level =4 ,轉儲Library cache對象,只包含基本信息
Level =8 ,轉儲Library cache對象,包含詳細信息(包括child references,pin waiters等)
Level =16,增加heap sizes信息
Level =32,增加heap信息
Library cache由一個hash表組成,而hash表是一個由hash buckets組成的數組,每個hash bucket都是包含library cache handle的一個雙向鏈表(每個hash bucket中可能包含多個library cache handle),每個Library Cache Handle指向Library Cache Object(如SQL),含對象名,namespace,時間戳,引用列表,鎖定對象及pin對象列表等。另外Library Cache Handle指向Library Cache Object和一個引用列表。
我們解釋一個簡單的軟分析過程,SQL語句經過hash之後,被對應到相應的hash bucket,然後在bucket中查找對應的library cache handle,然後在library cache handle對應的引用列表中檢查依賴關係等等,最後根據heap descriptor,指向相應的heap memory。這個heap memory包含的就是Diana Tree,P-Code,Source Code,Shared Cursor Context area等重要數據,也就是我們通常所說的,解析過的SQL及執行計劃樹,真正到這裏以後,sql才得以共享.也就真正的避免了硬解析

"library cache pin" 是用來管理library cache的併發訪問的,pin一個object會引起相應的heap被載入內存中(如果此前沒有被加載),Pins可以在三個模式下獲得:NULL,SHARE,EXCLUSIVE,可以認爲pin是一種特定形式的鎖,當Library Cache Pin等待事件出現時,通常說明該Pin被其他用戶已非兼容模式持有。
以下語句可以獲得library cache pin的被等待的session信息

代碼:


SELECT a
.SID, a.username, a.program, b.addr, b.kglpnadr, b.kglpnuse,
       
b.kglpnses, b.kglpnhdl, b.kglpnlck, b.kglpnmod, b.
kglpnreq
  FROM v$session a
,
x$kglpn b
WHERE a
.saddr = b.
kglpnuse
   
AND b.kglpnmod <>
0
   
AND b.kglpnhdl IN (
SELECT p1raw
                        FROM v$session_wait
                       WHERE event LIKE
'library%'
)
.


以下語句可以獲得被等待的session正在執行的語句:

代碼:


SELECT sql_text
  FROM v$sqlarea
WHERE
(v$sqlarea.address, v$sqlarea.hash_value) IN (
          
SELECT sql_address,
sql_hash_value
            FROM v$session
           WHERE SID IN
(
                    
SELECT SID
                      FROM v$session a
,
x$kglpn b
                     WHERE a
.saddr = b.
kglpnuse
                       
AND b.kglpnmod <>
0
                       
AND b.kglpnhdl IN (
SELECT p1raw
                                FROM v$session_wait
                                WHERE event LIKE
'library%'
)))
.


2、管理data buffer
oracle的data buffer默認只有default pool,實際上,data buffer在9i中可以分爲db_cache_size,db_keep_cache_size與db_recycle_cache_size,而且db_cache_size還可以根據塊大小劃分db_2k_cache_size,4k/8k/16k/32k等不同的buffer區域。對於9i以前版本,則由對應的db_block_buffers, buffer_pool_keep, buffer_pool_recycle等參數決定。
這些參數可以通過如下命令來修改
SQL> alter system set db_keep_cache_size = xxxx scope = both;
一般而言,如果不是特殊指定,所有對象都是存放在default pool中,並且按照特定的LRU算法工作,如果要指定一個對象要keep或者是recycle pool,可以通過如下的語法指定。
SQL>alter table table_name storage(buffer_pool keep);
最後,如果想知道對象處於什麼pool中,簡單的可以在user_segments中查詢獲得。
SQL> select t.segment_name,t.buffer_pool from user_segments t;

如果想計算一個對象在data buffer中佔用了多少空間(塊),則可以採用如下方法

代碼:


SELECT DATA_OBJECT_ID
, OBJECT_TYPE
  FROM DBA_OBJECTS
WHERE OBJECT_NAME
= UPPER('xxx'
);

SELECT COUNT(*)
BUFFERS
  FROM V$BH
WHERE objd
= xxx
;
.


data buffer也可以被清空,在Oracle9i裏,Oracle提供了一個內部事件,用以強制刷新Buffer Cache,其語法爲:
SQL>alter session set events 'immediate trace name flush_cache level 1';
或者:
SQL>alter session set events = 'immediate trace name flush_cache';
類似的也可以使用alter system系統級設置:
SQL>alter system set events = 'immediate trace name flush_cache';
在Oracle10g中,Oracle提供一個新的特性,可以通過如下命令刷新Buffer Cache:
SQL>alter system flush buffer_cache;

另外,oracle 9i可以支持在sga_max_size設置的範圍內,在線調整不同的內存區大小。在oracle 10g中,內存管理又有了新的變化,oracle默認將自動管理內存的分配,而不需要手工干預共享池與data buffer的大小。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章