探索系列——神人steve adams之著oracle8i interal service(十三)

wisdomone1發表於2010-04-25
因為它們在本地會全部解決(或者處理)。如果這些等待所花時間從平均上講長於10 centisecond,此時lmdn程式就會超負荷工作.


instance lock acquisition
   一旦得到一個鎖控制程式碼,需要一個例項鎖的程式會構建併傳送第二個訊息給lmdn程式用來轉換鎖.這個訊息會標識鎖控制程式碼,指定或說明新的所需要鎖模式,還要配置另外的一些選項.
如果資源的主節點是已知的,這個往上可能直接發給主節點的lmdn程式,當然這依賴於_lm_direct_sends引數,在oracle8.1中它預設為all,僅僅在oracle8中是lkmgr.
   如果資源的主節點依舊是未知的,本地lmdn程式傳送一個訊息給目錄結點,查詢哪個結點是資源的主節點.如果一個主節點沒有被分配,目錄節點會分配或指派一個主節點。根據資源型別,the lock mastering(我譯為鎖駐于于對應主節點上面的這個操作機制),即可以迴圈性或週期性分配給所有活動的節點,或者分配給初始發起的例項(條件是這個資源不可能在其它例項中使用).
一旦主節點可知(或確定了),獲取或轉變請求可以forwarded給主節點.
   
   如果主節點上面的鎖資訊表明,鎖是馬上被授予的,於是這個鎖會被在同時在主節點和本地節點連結到被授予的佇列上,同時一個轉變ast訊息返回給客戶端程式(透過客戶端例項的lmnd程式)。否則,鎖被連結到這個資源的轉化佇列上,客戶端程式繼續等待.

   當一個鎖請求被阻塞(也就是不能馬上得到鎖),主節點的lmdn程式可能要求或詢問鎖持有者降低它們對於資源的鎖模式,為了允許新的轉變請求可以被授予.透過傳送一個阻塞非同步trap可以實現它,或者bast,給阻塞程式和例項.鎖持有者是否能收到這個bast訊息,它樂於或願意降級鎖級別,這些可以鎖獲取或轉變期間進行配置.當一個阻塞程式遵從一個bast,它會傳送(回覆)ast確認或完成訊息.


   gv$dlm_locks顯示例項鎖資料庫中所有被阻塞及阻塞鎖的一切細節資訊,包括獲取和轉化鎖的一切選項配置資訊。gv$dlm_all_lock展示相同的細節資訊,但只是針對性於所有的例項鎖,包括 以null mode持有的鎖.



lckn processes
     一些例項鎖並不能直接經過需要鎖的程式哪裡獲取(得到).相反,lckn程式代表整個資料庫獲取它們.lckn程式以非同步方式操作它們.也就是說,當它們給lmdn程式發請求時,它們不會等待返回一個ast獲取或轉換確認.相反,它們會繼續處理來自其它程式的其它鎖請求.這就是為何在同步和非同步global lock gets和conversions之間gv$sysstat統計資訊有顯著的區別。


     預設情況下,僅僅會開啟一個lckn程式.正常情況這就足夠了,因為它以非同步方式操作.但是,如果lck0非常活躍(可以理解很busy),另外如果os不支援優先順序固定機制priority fixing,這時lck0可能必須要排隊等待cpu,因此會降低整個系統效能.如果是這樣的話,可以用_gc_lck_procs開啟多個lckn程式.



    


lock value blocks
     當一個程式需要或轉化(變)一個例項鎖時,它可能讀寫16byte位元組lock value block鎖值塊,這個鎖值塊是在主節點的資源結構進行維護的.比如,sm(smon)例項鎖資源的lock value block鎖值塊表示smon程式在任何例項上次執行時間last time.使用鎖值塊工具或機制也可以與多個例項間的scn進行通訊,建立並行執行通訊路徑或通道.但是鎖值塊不能用於大多數資源型別.


     再多說一點,本地入隊local enqueue的資源結構也包含一個鎖值塊,但它很少使用.



global locks
     單例項資料庫中本地鎖保護的一些資源,在ops下需要全域性顯露(可以理解為這個資源必須在所有ops例項可見).只要需要這些本地鎖,也必須持有一個對應的例項鎖,以保護跨多個例項ops的資源.像這種從全域性性方面用於保護本地鎖的例項鎖,叫作全域性鎖global locks.但是,這個術語有時也可以通俗表示為所有資料例項鎖的一個同義詞或代言.




row cache instance locks
     row cache instance locks直接correspond對應local row cache enqueue locks.它們不會取代或替代本地鎖(後者),但會讓它們(後者:指本地鎖)進行全域性顯露.

     當一個程式需要一個row cache instance lock時,它發通知給lck0後臺程式,我想以例項的身份(或代表)得到這個鎖,等待一個row cache lock等待.當等待對應的本地鎖時也會記錄這個等待.lck0以非同步方式得到這個例項鎖.當lck0從lmdn處接受到ast獲取或轉變的資訊後,它會發一個資訊給等待程式.

     當本地程式release它的row cache enqueue lock時,仍舊會快取dictionary row,因此例項鎖沒有release,但會透過lck0程式在後臺降級到null mode.但是,如果dictionary cache條目從共享池中被刷出,則會release row cache instance lock。


     雖然dictionary cache 條目和row cache enqueue locks在共享池中動態分配,但是它們對應的例項鎖的鎖狀態資訊lock state information不是這樣.這些鎖狀態資訊是在一個由_row_cache_instance_locks引數控制大小的一個固定佇列中進行維護.這個佇列的大小會限制每個例項可以快取多少個null mode的例項鎖,因此控制了row cache instance locks對於instance lock database例項鎖資料庫的資源使用程度或資源使用情況.
如果gv$rowcache顯示正在進行dlm_releases且沒有一些dlm_conflicts,可以考慮加大這個佇列的大小,快取這些處於工作狀態或正在執行狀態一系列的例項鎖.





global enqueues
    單例項資料庫的入隊鎖保護的大多數資源在ops下也要進行全域性顯露.這些就是全域性入隊.全域性入隊鎖可以被前臺或後臺程式獲取(當它們得到或持有一個本地鎖時).它們並不能被代表整個例項的lckn程式獲取.全域性入隊的例項鎖資源是動態分配的,像本地入隊資源一樣,它們不是永續性的.大多全域性入隊資源型別是以本地方式主導mastered locally,因為這些資源上面的鎖,其它例項很少會需要它們.


    最佳化全域性入隊locking的最簡潔實效方式,就是禁用表鎖table locking.確實,在ops下強烈建議這樣.在所有相關的表上使用alter table disable table lock比配置dml_locks為0更為明智.






cross-instance calls
    一個全域性入隊型別one global enqueue type完全值得特別提及或談論,因為例項內部或例項間通訊的規則.一些操作,如:改變表空間的備份狀態,日誌檔案操作,全域性檢查點操作,及其它操作,這些皆需要
全域性協調,因為實現這些操作時所有的例項必須要協力或配合工作.
    多個例項間的通訊是用ci(cross-instance call)enqueue入隊來實現.對於每種操作型別,每個例項的後臺程式持有這一系列資源的例項鎖.透過以不同模式操作鎖,有可能會觸發全域性行為或動作,同時等待這些全域性動作的完成.

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

相關文章