熱點塊競爭和解決--cache buffers chains
轉載並整理 熱點塊的定義 資料庫的熱點塊,從簡單了講,就是極短的時間內對少量資料塊進行了過於頻繁的訪問。定義看起來總是很簡單的,但實際在資料庫中,我們要去觀察或者確定熱點塊的問題,卻不是那麼簡單了。要深刻地理解資料庫是怎麼透過一些資料特徵來表示熱點塊的,我們需要了解一些資料庫在這方面處理機制的特性。
資料緩衝區的結構
我們都知道,當查詢開始的時候,程式首先去資料緩衝區中查詢是否存在查詢所需要的資料塊,如果沒有,就去磁碟上把資料塊讀到記憶體中來。在這個過程中,涉及到資料緩衝區中LRU鏈的管理(8i開始以接觸點計數為標準衡量buffer冷熱從而決定buffer是在LRU的冷端還是熱端),關於這部分內容,從oracle concepts 中就能得到詳盡的文件,我不準備去論述這部分內容,這也不是本文的重點。現在我們的重點是,到底程式是如何地去快速定位到自己所想要的block的,或者如何快速確定想要的block不在記憶體中而去進行物理讀的。 我們仔細想一想,隨著硬體的發展,記憶體越來越大,cache buffer也越來越大,我們如何才能在大量的記憶體中迅速定位到自己想要的block?總不能去所有buffer中遍歷吧!在此資料庫引出了hash的概念(oracle中快速定位資訊總是透過hash演算法的,比如快速定位sql是否在shared pool size中存在就是透過hash value來定位的,也就是說shared pool size中物件也是透過hash table來管理的),瞭解一點資料結構的基本知識就知道,hash 的一大重要功能就是快速地查詢。舉個最簡單的例子,假設我們有一個hash table 就是一個二維陣列a[200][100],現在有1000個無序數字,我們要從這1000個數字裡面查詢某個值是否存在,或者說當我們接收到某個數字的時候必須判斷是否已經存在,當然,我們可以遍歷這1000個數字,但這樣的效率就很低。但現在我們考慮這樣一種方法,那就是把1000個數字除以200,根據其餘數,放在a[200][100]裡面(假設相同餘數的最大數量不超過100),餘數就是陣列的下標。這樣,平均來說一個陣列a[i]裡面可能有5個左右的數字。當我們要去判別一個數字是否存在的時候,對這個數字除以200(這就是一個最簡單的hash演算法),根據餘數i作為下標去陣列a[i]中查詢,大約進行5次查詢就能判別是否已經存在,這樣透過開闢記憶體空間a[200][100]來換取了時間(當然hash 演算法的選取和hash table的大小是一個很關鍵的問題)。 明白了基本的hash原理之後,我們再來看oracle的block的管理。資料庫為這些block也開闢了hash table,假設是a,則在一維上的數量是由引數_db_block_hash_buckets 來決定的,也就是存在hash table a[_db_block_hash_buckets ],從oracle8i開始,_db_block_hash_buckets =db_block_buffers*2。而一個block被放到哪個buckets裡面,則是由block的檔案編號、塊號(x$bh.dbarfl、x$bh.dbablk對應了block的檔案屬於表空間中的相關編號和block在檔案中的編號,x$bh是所有cache buffer的header資訊,透過表格的形式可以查詢)做hash 演算法決定放到哪個bucket的,而bucket裡面就存放了這些buffers的地址。這樣當我們要訪問資料的時候,可以獲得segment的extent(可以透過dba_extents查到看,詳細的資訊來源這裡不做探討),自然知道要訪問的檔案編號和block編號,根據檔案和block編號可以透過hash演算法計算出hash bucket,然後就可以去hash bucket裡面去找block對應的buffer。 除此之外,為了維護對這些block的訪問和更改,oracle還提供了一種latch來保護這些block。因為要避免不同的程式隨意地徑直併發修改和訪問這些block,這樣很可能會破壞block的結構的。latch是資料庫內部提供的一種維護內部結構的一種低階鎖,latch的生存週期極短(微秒以下級別),程式加latch後快速的進行某個訪問或者修改動作然後釋放latch(關於latch不再過多的闡述,那可能又是需要另一篇文章才能闡述清楚)。這種latch數量是透過引數_db_block_hash_latches 來定義的,一個latch對應的保護了多個buckets。從8i開始,這個引數的default規則為: 當cache buffers 少於2052 buffers _db_block_hash_latches = power(2,trunc(log(2, db_block_buffers - 4) - 1)) 當cache buffers多於131075 buffers _db_block_hash_latches = power(2,trunc(log(2, db_block_buffers - 4) - 6)) 當cache buffers位於2052與131075 buffers之間 _db_block_hash_latches = 1024 透過這個規則我們可以看出,一個latch大約可以維護128個左右的buffers。由於latch使得對block的操作的序列化(9i中有改進,讀與讀可以並行,但讀與寫、寫與寫依然要序列),很顯然我們可以想到一個道理,如果大量程式對相同的block程式進行操作,必然在這些latch上造成競爭,也就是說必然形成latch的等待。這在宏觀上就表現為系統級的等待。明白了這些原理,為我們下面的在資料庫中的診斷奠定了基礎
我們還有另外一種方式 select object_name ) ) ;
…………………… 到這裡我們基本能找到熱點塊對對應的物件。但實際上還有另外一個途徑來獲取這些資訊,那就是和x$bh.tch 相關的一種方法。對於8i開始oracle提供了接觸點(touch count)來作為block是冷熱的標誌,在一定條件滿足的情況下block被程式訪問一次touch count 增加一,到某個標準之後被移動到LRU熱端(關於touch count 在這裡不做詳細介紹,那又將是一大篇文章)。那在短時間內從某種意義上講,touch count 大的block可能暗示著在當前某個週期內被訪問次數比較多。 select distinct a.owner,a.segment_name,a.segment_type from dba_extents a, where rownum < 11) b and a.block_id + a.blocks > b.dbablk; OWNER SEGMENT_NAME SEGMENT_TYPE 同上面一樣還有這個方法 select object_name where rownum < 11) ;
10 rows selected.
熱點問題的解決 熱點塊和熱點物件我們都找到了,但是我們該怎麼來解決這個問題呢?一般來說,熱點塊會導致cache buffers chains競爭等待,但並不是說cache buffer chains一定是因為熱點塊而起,在特別情況下有可能是因為latch數量的問題導致的,也就是一個latch管理的buffers數量太多而導致競爭激烈。但是latch數量我們一般是不會輕易去設定的,這是oracle的隱藏引數。 實際上最有效的辦法,是從最佳化sql入手,不良的sql往往帶來大量的不必要的訪問,這是造成熱點塊的根源。比如本該透過全表掃描的查詢卻走了索引的range scan,這樣將帶來大量的對塊的重複訪問。從而形成熱點問題。再或者比如不當地走了nested loops的表連線,也可能對非驅動表造成大量的重複訪問。那麼在這個時候,我們的目標就是找出這些sql來並嘗試最佳化。在statspack報告中,根據報告中sql列表,我們如果是透過dba_extents確定的熱點物件而不是透過dba_objects確定的,則可以透過查詢出的熱點segment轉換為對應的表,對於非分割槽的索引,index_name就是segment_name,透過dba_indexes很容易的找到對應的table_name,對於分割槽表和分割槽索引也能透過和dba_tab_partition和dba_ind_partitions找到segment和table的對應關係。透過這些table到statspack報告中去找相關的sql。 select sql_text from dba_extents a, where rownum < 11) b and a.block_id + a.blocks > b.dbablk) b SQL_TEXT 20 rows selected. |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25462274/viewspace-1994938/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- cache buffers chains and cache buffers lru chainsAI
- 熱點塊競爭與解決
- cache buffers chains vs cache buffers lru chainAI
- latch: cache buffers chainsAI
- latch: cache buffers chains-熱塊的簡單模擬實驗AI
- latch:cache buffers chains解決步驟AI
- latch:cache buffers chains案例AI
- 用於排查cache buffers chainsAI
- Cache Buffers chains,存在共享模式?AI模式
- 深入理解latch: cache buffers chainsAI
- Trouble shooting latch: cache buffers chainsAI
- ORACLE等待事件latch: cache buffers chainsOracle事件AI
- 等待事件_cache_buffers_chains_latch事件AI
- 使用了索引就一定能避免cache buffers chains爭用嗎索引AI
- 解決一例latch:cache buffers chains小記AI
- latch:cache buffers chains的優化思路AI優化
- buffer cache實驗6-latch:cache buffers lru chainsAI
- latch:cache buffers chains的最佳化思路AI
- latch: cache buffers chains---AWR實戰分析AI
- 模擬cache buffers chains與library cache pin等待事件AI事件
- latch: cache buffers chains故障處理總結(轉載)AI
- 一次latch cache buffers chains問題的處理AI
- 0821Cache Buffers chains與共享模式疑問4AI模式
- 0330Cache Buffers chains與共享模式疑問AI模式
- 處理 latch_cache_buffers_chains等待事件一例AI事件
- 0330Cache Buffers chains與共享模式疑問2AI模式
- 1104Cache Buffers chains與共享模式疑問3AI模式
- 1104Cache Buffers chains與共享模式疑問4AI模式
- buffer busy waits, latch cache buffers chains, read by other session區別AISession
- Bug 3797171 cache buffers chains latch contention increased in 10g-3797171.8AI
- CACHE BUFFER CHAINSAI
- cache buffers lru chainAI
- Oracle Cache Buffer ChainsOracleAI
- Latch: cache buffer chains (%)AI
- cache buffers LRU chain latchAI
- latch free(cache buffers chain)AI
- 【恩墨學院】深入剖析:關於cache buffers chains的經典案例處理詳解?AI
- 資料緩衝區熱鏈和熱塊爭用及解決方法