Latch free等待事件三

jss001發表於2009-02-15

Oracle 10g 作業系統solaris

Db_cache_size

32m

64m

128m

256m

512m

1024m

2048m

_ksmg_granule_size

4m

4m

4m

4m

4m

16m

16m

_db_block_buffers

3976

7952

15904

31808

63616

127232

254464

_db_block_hash_buckets

8192

16384

32768

65536

131072

262144

524288

_db_block_hash_latches

1024

1024

1024

1024

1024

1024

2048

Oracle9i 作業系統solaris

Db_cache_size

32m

64m

128m

256m

512m

1024m

2048m

_ksmg_granule_size

4m

4m

16m

16m

16m

16m

16m

_db_block_buffers

4000

8000

16016

32032

64064

128128

256256

_db_block_hash_buckets

8009

16001

32051

64067

128147

256279

512521

_db_block_hash_latches

1024

1024

1024

1024

1024

1024

2048

Oracle8i 作業系統solaris

Db_block_buffers

4000

8000

16016

32032

64064

128128

192192

_db_block_hash_buckets

8000

16000

32032

64064

128128

256256

384384

_db_block_hash_latches

1024

1024

1024

1024

1024

1024

2048

Cache buffers chains latch爭用原因一 ―― 低效的sql語句

低效的sql語句是導致cache buffers chains latch爭用的主要原因。在高併發系統中, atch free時間可能因此非常明顯。典型的情況是,應用程式開啟多個併發會話執行相同的低效sql,並且訪問同樣的資料集。

你應該時刻銘記下面三點:

n 每次邏輯讀都需要請求一次latch

n 只有獲得某個latch之後才會停止對該latch的不斷請求。

n 在某個時刻,只有一個程式可以獲得cache buffers chains latch,而該latch可能用於保護很多的資料塊,其中的某些塊可能正在被其他程式請求(當然,前面也已經提過,oracle9i允許只讀性質的cache buffers chains latch共享)。

一般而言,較少的邏輯讀意味著較少的latch請求,也就意味著較少的latch爭用和更好的系統效能。所以,你應該找出導致cache buffers chains latch爭用的低效sql語句,最佳化這些語句,儘量降低其邏輯讀。那些buffers_get/executions比值較大的sql可能就是你需要調整的語句。

1:某些dba可能透過修改隱含引數_db_blocks_hash_latches來增加系統中cache buffers chains latch的個數,而不是首先去最佳化低效的sql語句,這是不正確的,增加latch能暫時降低對latch的爭用,但這是治標不治本的方法。

2:在sun solareis平臺上,我們將一個資料庫從oracle8.1.7.4升級到oracle9.2.05之後,發現了大量的cache buffers chains latch爭用,新的最佳化器為應用程式生成了低效的執行計劃。一些隱藏的最佳化器相關的引數,在oracle8i中是無效的,但在oracle9i中有效。在重設這些引數後,問題得意解決。如果你遭遇到同樣的情況,建議請求oracle的技術支援。

Cache buffers chains latch爭用原因二 ―― 熱點塊

熱點塊是導致cache buffers chains latch爭用的另外一個主要原因。當多個程式重複訪問一個或多個由同一個cache buffers chains latch保護的塊時會導致該問題。這通常是應用程式引起的。在這種情況下,增加cache buffers chains latch的個數對熱點塊導致的爭用沒有什麼作用。因為資料塊分佈在哪個hash buckethash chain上是由塊地址(dba:data block address)hash bucket的個數決定的,和hash latch的個數沒有關係。只要塊地址和hash bucket數沒有改變,這些熱點塊還是會分佈在原來的hash buckethash chain上,還是由原來的hash latch保護,那麼就還會對這些hash latch產生爭用。除非系統中latch數目顯著的增加(這樣每個latch管理的hash bucket就會很少,甚至一個latch管理一個hash bucket,這樣原來的熱點塊可能就會有其他的幾個latch來管理,而不再需要爭用原來的那個latch)。

解決這樣的cache buffers chains latch爭用,最好的方法是找出熱點塊。透過latch free等待事件的p1raw引數可以知道是否是因為熱點塊導致了latch爭用。(在oracle10g中,cache buffers chains latch的相關等待事件不再是latch free,而是cache buffers chains)。P1raw引數是latch的地址。如果多個會話都在等待同一個latch地址,那麼恭喜你遇到熱點塊問題了。下面的例子中,可以發現由地址為00000400837d7800 00000400837de400latch保護的hash chain中存在熱點塊(多個會話都在等待這兩個地址的latch)。

Select sid, p1raw, p2, p3, seconds_in_wait, wait_time, state
from v$session_wait
where event =’latch free’
order by p2, p1raw;

sid p1raw p2 p3 seconds_in_wait wait_time state
---- ---------------- --- --- --------------- ---------- ------------------
38 00000400837d7800 98 1 1 2 waited known time
42 00000400837d7800 98 1 1 2 waited known time
44 00000400837d7800 98 3 1 4 waited known time
58 00000400837d7800 98 2 1 10 waited known time
85 00000400837d7800 98 3 1 12 waited known time
214 00000400837d7800 98 1 1 2 waited known time
186 00000400837d7800 98 3 1 14 waited known time
149 00000400837d7800 98 2 1 3 waited known time
132 00000400837d7800 98 2 1 2 waited known time
101 00000400837d7800 98 3 1 4 waited known time
222 00000400837d7800 98 3 1 12 waited known time
229 00000400837d7800 98 3 1 4 waited known time
230 00000400837d7800 98 3 1 11 waited known time
232 00000400837d7800 98 1 1 20 waited known time
257 00000400837d7800 98 3 1 16 waited known time
263 00000400837d7800 98 3 1 5 waited known time
117 00000400837d7800 98 4 1 4 waited known time
102 00000400837d7800 98 3 1 12 waited known time
47 00000400837d7800 98 3 1 11 waited known time
49 00000400837d7800 98 1 1 2 waited known time
99 00000400837d9300 98 1 1 32 waited known time
51 00000400837dd200 98 1 1 1 waited known time
43 00000400837de400 98 1 1 2 waited known time
130 00000400837de400 98 1 1 10 waited known time
89 00000400837de400 98 1 1 2 waited known time
62 00000400837de400 98 0 1 -1 waited known time
150 00000400837de400 98 1 1 9 waited known time
195 00000400837de400 98 1 1 3 waited known time
67 00000400837de400 98 1 1 2 waited known time

下一步,就是找出這些熱點塊以及造成latch爭用的sql語句。這是因為cache buffers chains latch通常保護很多個塊,這些熱點塊可能屬於這些sql中使用的某個表。從oracle8i開始,你可以透過接觸點計數(tchtouch count)來發現熱點塊。一般來說,熱點塊的tch會比較高。但是要記住,當塊從lru列表的冷端移動到熱端後,tch會被清0。所以, tch0的塊不一定就不是熱點塊。

-- 這裡使用了前面例子中的p1raw (00000400837d7800).

Select a.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name

from x$bh a, dba_objects b

where (a.obj = b.object_id or a.obj = b.data_object_id)

and a.hladdr = ’00000400837d7800’

union

select hladdr, file#, dbablk, tch, obj, null

from x$bh

where obj in (select obj from x$bh where hladdr = ’00000400837d7800’

minus

select object_id from dba_objects

minus

select data_object_id from dba_objects)

and hladdr = ’00000400837d7800’

order by 4;



hladdr file# dbablk tch obj object_name

---------------- ----- ------- ---- ----------- --------------------

00000400837d7800 16 105132 0 19139 route_history

00000400837d7800 16 106156 0 19163 telco_orders

00000400837d7800 26 98877 0 23346 t1

00000400837d7800 16 61100 0 19163 telco_orders

00000400837d7800 16 26284 0 19059 fp_eq_tasks

00000400837d7800 7 144470 0 18892 report_process_queue

00000400837d7800 8 145781 0 18854 pa_equipment_union

00000400837d7800 249 244085 0 4294967295

00000400837d7800 7 31823 1 18719 candidate_events

00000400837d7800 13 100154 1 19251 event

00000400837d7800 7 25679 1 18730 candidate_zoning

00000400837d7800 7 8271 1 18719 candidate_events

00000400837d7800 7 32847 2 18719 candidate_events

00000400837d7800 8 49518 2 18719 candidate_events

00000400837d7800 7 85071 2 18719 candidate_events

00000400837d7800 275 76948 2 4294967295

00000400837d7800 7 41039 3 18719 candidate_events

00000400837d7800 7 37967 4 18719 candidate_events

00000400837d7800 8 67950 4 18719 candidate_events

00000400837d7800 7 33871 7 18719 candidate_events

00000400837d7800 7 59471 7 18719 candidate_events

00000400837d7800 8 8558 24 18719 candidate_events

如前所述,熱點塊通常是應用程式導致的。找出這些程式,檢查他們為什麼重複訪問相同的塊,並且做出相應的調整。

另外一個解決辦法,就是儘量將熱點塊分配到不同的hash chain連結串列,由不同的cache buffers chains latch來保護。這可以透過調整熱點塊中的行資料分佈到不同的塊中來實現。新的塊有不同的塊地址,這樣原來在同一個hash chain上的資料就可能會分佈到其他不同的hash chain上。改變塊中行資料的分佈有很多方法,包括:

n 透過rowid刪除並且重新插入某些行。

n 將表exp出來,加大 pctfree,然後再imp表。這樣會使每個塊中的資料減少,使資料分佈到更多的塊上。同時,也會導致佔用更多的空間,全表掃描的效能也會受到影響。

n[@more@]

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

相關文章