Shared Pool Latch和Library Cache Latch競爭:

這兩個Latch是Shared Pool管理中最重要也是最常見的Latch競爭。

Shared Pool Latch用于共享池中內(nèi)存空間的分配和回收,如果SQL沒有充分共享,反復(fù)解析,那么將會不斷請求Shared Pool Latch在共享池中分配空間,由此可能造成非常嚴(yán)重的CPU消耗。

Library Cache Latch用于保護(hù)Cache在內(nèi)存中的SQL以及執(zhí)行計(jì)劃等,當(dāng)需要向Library Cache中增加新的SQL時,Library Cache Latch必須被獲得。在解析SQL過程中,Oracle需要搜索Library Cache查找匹配的SQL,如果沒有可共享的SQL代碼,Oracle將全新解析SQL,獲得Library Cache Latch向Library Cache中插入新的SQL代碼。Library Cache Latch的數(shù)量受一個隱含參數(shù)_kgl_latch_count控制,其缺省值為大于或等于CPU_COUNT的最小素?cái)?shù),最大值不能超過67。

可以簡化一下SQL的執(zhí)行過程,以說明這兩個Latch在SQL解析過程中所起的作用。

⑴ 首先需要獲得Library Cache Latch,根據(jù)SQL的HASH_VALUE值在Library Cache中尋找是否存在可共享的代碼。如果找到則為軟解析,Server進(jìn)程獲得該SQL執(zhí)行計(jì)劃,轉(zhuǎn)向第⑷步;如果找不到共享代碼則執(zhí)行硬解析。
⑵ 釋放Library Cache Latch,獲得Shared Pool Latch,查找并鎖定自由空間。
⑶ 釋放Shared Pool Latch,重新獲得Library Cache Lacth,將SQL及執(zhí)行計(jì)劃插入到Library Cache中。
⑷ 釋放Library Cache Latch,保持Null模式的Library Cache Pin/Lock。
⑸ 開始執(zhí)行。

通過以上過程可以看到,如果系統(tǒng)中存在過度的硬解析,系統(tǒng)的性能必然受到反復(fù)解析、Latch爭用的折磨。通過查詢v$sysstat視圖獲得關(guān)于數(shù)據(jù)庫解析的詳細(xì)信息:

sys@NEI> select name,value from v$sysstat where name like 'parse%';
NAME                                  VALUE
------------------------------ ------------
parse time cpu                         6565
parse time elapsed                   507494
parse count (total)                  680519
parse count (hard)                    18731
parse count (failures)                   39

通過(parse count (total) - parse count (hard))/parse count (total)得出的軟解析率經(jīng)常被用作衡量數(shù)據(jù)庫性能的一個重要指標(biāo)。

對于version_count過高的問題,可以查詢v$sql_shared_cursor視圖,這個視圖會給出SQL不能共享的具體原因,如果是正常因素導(dǎo)致的,相應(yīng)的字段會被標(biāo)記為“Y”;對于異常的情況,查詢結(jié)果可能顯示的都是“N”,這就表明Oracle認(rèn)為這種行為是正常的,在當(dāng)前系統(tǒng)設(shè)置下,這些SQL不應(yīng)該被共享,那么可以判斷是某個參數(shù)設(shè)置引起的。和SQL共享關(guān)系最大的一個初始化參數(shù)就是cursor_sharing。當(dāng)cursor_sharing參數(shù)為similar,并且數(shù)據(jù)庫存在相關(guān)柱狀圖(histograms)信息時,對于每一條新執(zhí)行的SQL,Oracle都通過硬解析以獲得更為精確的執(zhí)行計(jì)劃,這最終導(dǎo)致了version_count過高,這是cursor_sharing=similar的正常行為,并非Bug。

了解了這個行為之后,解決這個問題也就不復(fù)雜了,可以將cursor_sharing設(shè)置為Exact或者Force以避免此問題,或者通過刪除柱狀圖(Histograms)來防止不必要的硬解析,實(shí)際上,如果數(shù)據(jù)不存在失衡分布,我們也不必要收集柱狀圖信息。

從中得到啟是,當(dāng)需要設(shè)置某些特殊的參數(shù)來影響數(shù)據(jù)庫的行為時,必須了解這些設(shè)置會給數(shù)據(jù)庫帶來的影響,這樣一方面可以避免問題的出現(xiàn),另一方面在問題出現(xiàn)時,我們可以快速地發(fā)現(xiàn)問題根源并解決問題。