- 論壇徽章:
- 0
|
晶晶實(shí)驗(yàn)十四 Library cache 篇
第一小結(jié) library cache 的內(nèi)存結(jié)構(gòu)
Library cache的作用,最主要的就是存儲(chǔ)已解析的SQL聲明,避免硬解析。我們可以通過一個(gè)視圖V$librarycache來了解Library cache點(diǎn)中率,已此來評(píng)估SQL聲明的解析情況。應(yīng)時(shí)時(shí)注意此視圖中點(diǎn)中率情況,好及時(shí)發(fā)現(xiàn)并解決問題。
一、Library cache中所存儲(chǔ)的信息:
1. 按對(duì)象類型分類:
共享游標(biāo)(SQL and PL/SQL objects)、數(shù)據(jù)庫對(duì)象(tables, indexes, and so on)
2. 按存在時(shí)間分類:
存貯對(duì)象:如表、索引、視圖等(老化后 磁盤上還有 所以叫永久存儲(chǔ) 并不是永久存儲(chǔ)在LIBRARY 中)
瞬時(shí)對(duì)象:如游標(biāo)(老化后就沒有了)(簡(jiǎn)單了解在Library cache中數(shù)據(jù)庫對(duì)象的信息是什么)
二、Library cache中如何存儲(chǔ)信息
了解Library cache的簡(jiǎn)單原理,對(duì)于理解一些調(diào)優(yōu)概念,是十分必要的。
共享池內(nèi)存的結(jié)構(gòu),是計(jì)算機(jī)中常用的哈希表形式的擴(kuò)展。常用的哈希表形式,總是先有一個(gè)哈希表,保存對(duì)象地址(或句柄),然后,根據(jù)對(duì)象地址(或句柄)訪問對(duì)象,計(jì)算機(jī)中常以這種方式組織數(shù)據(jù)。其基本形式如下:
library.gif (17.71 KB, 下載次數(shù): 144)
下載附件
2008-10-06 11:35 上傳
注意地址和句柄的區(qū)別,一般來說,地址只是一個(gè)位置信息。而句柄,除了位置,還包含一些其他信息。
還要注意“堆(Heap)”的概念,程序開發(fā)者在程序員使用系統(tǒng)函數(shù)分配的內(nèi)存。
注:此處補(bǔ)充一點(diǎn)概念,除了堆之外,還有棧,也是內(nèi)存中比較常見的名詞。開發(fā)者在程序中定義的各種變量,就在棧中分配。
上圖每一組哈希值、鏈表頭,叫做一個(gè)哈希桶。簡(jiǎn)單的說就是:哈希桶(Hash Bucket)指向?qū)ο缶浔∣bject Handles),對(duì)象句柄存有對(duì)象所占的堆內(nèi)存的地址。由于對(duì)象的堆往往不只一個(gè),Oracle習(xí)慣稱這些堆為子堆。通常,對(duì)象句柄中存有0號(hào)子堆的地址,而0號(hào)子堆中存有其他各個(gè)子堆的地址,而Library cache中所存貯對(duì)象的信息,就在從0號(hào)開始的各個(gè)子堆中。
第二小節(jié) Library cache的PIN與LOCK
一、詳述Library cache lock與Library cache pin
1.
Library cache lock與Library cache pin的模式。
所有在Library cache中的對(duì)象,都由兩部分組成,一個(gè)句柄、至少一個(gè)子堆。這一點(diǎn)可以參考上面的圖。
句柄中記錄的有對(duì)象的名字、命名空間、Lock的持有者和等待者、Pin的持有者和等待者、一些標(biāo)志信息,最重要的,句柄中記有堆的地址。
在Library cache中尋找對(duì)象時(shí),先計(jì)算HASH值,在HASH表中找到句柄,再經(jīng)由句柄,找到對(duì)象實(shí)際的內(nèi)存地址。在這個(gè)過程中,有兩個(gè)重要的數(shù)據(jù)項(xiàng)需要被鎖保護(hù)起來。一個(gè)是對(duì)象句柄、另一個(gè)就是對(duì)象的內(nèi)存堆。在對(duì)象句柄上加的鎖就是Library cache lock,在內(nèi)存堆上加的鎖,就是Library cache pin。
下面先討論一下Library cache lock。
(1)。 Library cache lock
Locks 除了阻止不相容的對(duì)句柄的訪問,以保護(hù)句柄中數(shù)據(jù)的完整性外,獲得Locks也是在緩存中定位對(duì)象的唯一方式,即:進(jìn)程在對(duì)句柄上加鎖的同時(shí),完成在內(nèi)存中定位堆的操作。
在句柄上獲得Lock、并在內(nèi)存中定位到堆后,對(duì)象可以Pin自己的堆。如果對(duì)象相關(guān)信息不在內(nèi)存中,Pinning一個(gè)對(duì)象將導(dǎo)致它和它的的子堆被裝載(此種情況時(shí),如果是多個(gè)對(duì)象Pin一個(gè)對(duì)象,將可能會(huì)造成Pin等待)
Lock 有三種模式
· Share(s) : 讀對(duì)象
· Exclusive(x) : 修改或創(chuàng)建對(duì)象
· Null(n) : 專用于為會(huì)話持續(xù)
注意: 存貯對(duì)象可以被鎖在以上任意一種方式,瞬時(shí)對(duì)象只能被鎖在Null方式。
Null 鎖在執(zhí)行SQL聲明的解析階段被獲得,此后一直持有。它不阻止任何DDL。也用術(shù)語“易碎解析鎖”稱乎它(breakable parse lock)。
在以下兩種情況下Null鎖被打碎:
· 當(dāng)鎖所在對(duì)象有一個(gè)獨(dú)占Pin時(shí)
· 鎖所在對(duì)象的任何依賴對(duì)象有一個(gè)獨(dú)占Pin時(shí)
(2)。Library cache pin:
Pin有兩種模式:
· Share (s) : 讀一個(gè)對(duì)象堆
· Exclusive (x) : 修改一個(gè)對(duì)象堆
無論存貯對(duì)象還是瞬時(shí)對(duì)象,都能被Pinned在Share或Exclusive模式。當(dāng)修改對(duì)象時(shí),進(jìn)程首先會(huì)以Share模式Pin對(duì)象,進(jìn)行錯(cuò)誤和安全檢查,然后在以Exclusive模式Pin住對(duì)象。Pin的解除將會(huì)導(dǎo)致相關(guān)對(duì)象上的易碎鎖Break
不同類型的操作所需要的不同類型的lock/pin:
1).
所有的DDL操作都會(huì)在需要處理的對(duì)象上放一個(gè)Exclusive(排他)類型的Lock和Pin(僅僅當(dāng)執(zhí)行的時(shí)候加上)。
如:重編譯,截?cái)啾?給對(duì)象授權(quán),等等
2).
所有對(duì)對(duì)象的使用都需要一個(gè)null類型lock和shared類型的pin(僅僅當(dāng)執(zhí)行的時(shí)候加上)。如:使用視圖,執(zhí)行過程,等等。
以上規(guī)則,也同樣應(yīng)用于對(duì)象所有依賴的對(duì)象。如:一個(gè)依賴于其他視圖的視圖,一個(gè)依賴于其他包的包。
下面我們用一個(gè)例子,來驗(yàn)證一下Library cache lock/pin。
例10:觀察Library cache lock/pin 的狀態(tài):
先建立一下如下過程:
create or replace procedure jj_cur is
cursor aa is select kglhdlmd,kglhdpmd
from x$kglob where kglnaobj='select * from aa_1 where id=1' and kglhdadr<>kglhdpar;
kk number:=5;
kk1 number:=5;
begin
for i in 1..2000 loop
kk:=5;
kk1:=5;
open aa;
fetch aa into kk,kk1;
dbms_output.put_line(kk||'-'||kk1);
close aa;
end loop;
end;
/
Kglhdadr是游標(biāo)句柄,而Kglhdpar是父游標(biāo)句柄,條件中的kglhdadr<>kglhdpar ,目的是只顯示子游標(biāo)。Kglhdlmd是Library cache lock的模式,為0時(shí)表示沒有鎖,1是NULL鎖,2是共享鎖,3是獨(dú)占鎖。Kglhdpmd是Library cache pin的模式,0是沒有Pin,2是共享Pin,3是獨(dú)占Pin。
另外,我們作為測(cè)試用的SQL聲明select * from aa_1 where id=1,要保證只有一個(gè)子游標(biāo),這樣做的目的,就是讓過程中的游標(biāo)AA只選出來一條記錄。在過程執(zhí)行完畢后,最好再執(zhí)行聲明:select kglhdlmd,kglhdpmd from x$kglob where kglnaobj='select * from aa_1 where id=1' and kglhdadr<>kglhdpar一次,看一下能選出來幾行,如果多于一行,說明聲明子游標(biāo)的數(shù)量多于一條,應(yīng)該換一條聲明再試。
在會(huì)話A中:
spool e:\oracle\aaa.txt
exec jj_cur;
在會(huì)話B中:
select * from aa_1 where id=1;
在會(huì)話A中:
spool off
查看e:\oracle\aaa.txt,可以看到,在會(huì)話B的聲明執(zhí)行時(shí):Library cache lock先是1,然后是0。而Library cache pin先是3,后是2,然后是0。會(huì)話B中的聲明是第一次執(zhí)行,這是硬解析,所以會(huì)有很短時(shí)間的獨(dú)占Pin。上面的例子,可以再試一次,這次,就是軟解析了。試驗(yàn)過程同上,結(jié)果是,Library cache lock仍是1,然后是0,而Library cache pin則是2,然后是0,不再有3了。
我們可以再用上面的方法,測(cè)試一下父游標(biāo)上的鎖的情況,這里就略過了。
我記得有資料上說,聲明在解析時(shí),在父、子游標(biāo)上會(huì)有獨(dú)占鎖的,但是在上面的測(cè)試中,卻沒有看到。有可能是我的過程執(zhí)行速度不過快,無法捕找到句柄上的獨(dú)占鎖。 library.GIF (17.71 KB)
2008-3-8 00:28 |
|