探索系列_神人steve adams之著oracle8i interal service(四)

wisdomone1發表於2010-04-19
latches  閂
   sga中許多記憶體結構,需要oracle例項的資料庫程式併發訪問。但每一個時刻只能一個程式去修改它們。
因此oracle透過latches或lock來保護sga資料結構不被破壞.

   latches比lock的限制措施更多,它不允許多個程式同時檢查所要保護的資料結構,它們提供了排它訪問.然而
locks可以支援更好的併發,因為它們可以被共享模式持有(如果資料結構只是被檢查).
   (這意味著redo copy latches可以被共享,但與硬體相關)
另一種二者重要區別就是,請求排隊機制。如果以某種必要或順序請求某個locks,它們被先排隊.但latches不支援請求排隊。
如果請求一個latch失敗,因為這個latch正在忙。此時程式就直接重試直至成功得到latch.因此latch請求不一定(沒必要)依序服務.
    因為一個latch在同一個時間只能被一個程式持有,也沒有排隊這一說,latch資料結構本身很簡單,從本質上講,它只是用記憶體一個區域表示latch的狀態而已。
因為latch資料結構簡單,所以請求及free它基本不用作什麼工作(也就是不用花費過多的資源)。相比之下,locks的資料結構更為複雜,因為要支援排隊及併發。
因此請求,轉化,free它需要更多的工作要作.
    另一方面,oracle lock資料結構,有幾個部分,因此不能以原子性方式去修改它.從這個事情來講,oracle實際上用latch來保護對於locks的操作。當然使用什麼型別的
latch,這與lock型別有關。比如,cache buffer locks間接被cache buffers chain latches來保護,row cache enqueue lock被row cache object latch所保護.

    由於latches的高效性,oracle經常使用它,而非lock。



parent and child latches  父與子latch
  大多數內部的oracle資料結構,用一個latch就可以保護它了。但是,在一些情況下,需要多個latch。比如,為了保護library cache之中不同group的物件,需要好多library cache latches。
每個cache buffers chain latches保護每個database buffer cache hash chain.
   當出現多個latches保護一個結構(內部oracle資料結構),或者不同的等同結構,這些latch叫作child latches.對於相同型別的child latches的每個集合,也有一個parent latch.一般來講,
parent和child latches可能都需要了。但實際上,你可能只想得到這個library cache parent latch,甚至很少發生請示child latches(相比活動而言).
   大家看了以上,可能有點暈了,oracle也引用單獨(獨立的)的latch直接作parent latch,它並沒有child latch.因此v$latch_parent中,每種單獨的latch,只有一行記錄.每一個真正的parent
latches也是隻有一行記錄.v$latch_children對於每個child latch只有一行記錄。因此這兩個檢視的合併會顯示所有的latches.
順著oracle版本的不同,會使用不同型別的latches,它們可能是單獨或parent及child latches.

   v$latch根據每種latch顯示latch的概要資訊。它應是你第一個關注的地方(latch問題).如果發現是相同型別的latch集合,這下你就可以檢視v$latch_children分析在child latches的活動是否均勻,
透過v$latch_parent也會幫助你是否基於某個parent latch的活動有問題呢?
 

  latch gets 請求latch
 
當oracle程式訪問資料結構需要一個latch時,可以兩種方式get它,樂觀等待模式及悲觀等待模式(也叫立即模式)

樂觀等待模式
  發現latch不可用,馬上短暫spin然後再次嘗試get.當一個程式spins,它多次執行一系列簡單的指令,作為在重新嘗試get前的一種等待方法。從os的層面把這叫作一個活動的等待,因為程式仍舊在佔用cpu的週期,雖然它只是等待了一會.
嘗試再次get latch之前所花費的cpu time,很小及固定。(雖然在oracle7i用_latch_spin_count可以調節)。如果下次get latch又失敗了。這個過程或動作(spin)會一直持續到_spin_count引數的值.這個引數預設是2000 次重複(在多處理器環境中)

 
why spin? 為何要spin呢

  spinning這種思想,源於另一個程式在另一個cpu執行時,可能會釋放這個latch,因而允許spinning 程式繼貫執行。當然,如果僅一個cpu,這樣作毫無意義.
替代spinning的另一種方法,這個程式不用cpu了,讓另一個程式使用。初看,這是個好主意.但是,對於cpu而言,它要停止執行一個程式,而開始執行另一個程式,它必須進行一個上下文切錦。也就是說,它要儲存第一個停止程式的上下文資訊,用此確定下次排程哪個程式,然後
恢復下一個程式的上下文。一個程式的上下文,其實就是一系列的cpu註冊值(用此表示這個程式的準確狀態).
   上下文切換實施與具體的機器高度相關。事實上,典型它用匯編方式寫的。system供應商力求最小化上下文資料的大小,透過使用trick比如重對映記憶體地址而非複製資料來優它上下文切換.但是,上下文切換仍舊是一個昂貴的操作,因為各種各樣的核心資料結構要被查詢並更新.
訪問這些結構透過spinlocks的來保護,spinlocks就是os級的latches.在一個大量高負荷的system中,上下文切換正常會佔用1-3%左右的cpu時間.因此短暫的spinning可以避免它。這樣可以節省cpu time,進而請求latch的等待時間也會減少.基於以上原因,短暫spinning相對放棄cpu(馬上)更為明智.

 



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

相關文章