RAC 的併發控制

RAC下的併發控制

1.        DLM

dlm(分佈式鎖管理):記錄着哪個節點正在用哪種方式操作哪個數據,並負責協調解決節點間的競爭

舉例說明DLM的作用:

一個兩個節點的rac

2、節點1想要修改數據1

3、節點1向DLM請求,DLM發現數據1還沒有被任何節點使用,DLM就授權給節點1;並且DLM登記節點1對數據1的使用

4、節點2也想修改數據1,;

5、節點2向DLM請求,dlm發現數據1被節點1使用,dlm就會請求節點1“先給節點2使用”,節點1接到請求後釋放其對數據1的佔用,節點2能夠操作數據

6、DLM記錄這個過程

需要注意的是dlm負責的是節點間的協調,而節點內的協調不是dlm負責。

繼續上面的例子

1、現在節點2的進程1修改數據1;

2、節點2的進程2也想修改數據1;

3、節點2任然請求DLM,dlm發現節點2現在已經有權限,無須授權;

4、進程2對dlm的請求被通過,但是進程2是否能夠修改數據1,還需要進一步檢查;

5、通過傳統的鎖模式,比如“行級鎖”進程2發現數據1正被進程1修改,所以進程2只能等待。

oracle RAC徐澤的是以數據塊作爲粒度單位。也就是說進程想要修改記錄1時,向dlm提出的申請是“數據塊1的操作權限”,而不是“記錄1的操作權限”。

2.        dlm中資源和鎖

dlm協調集羣各節點對資源使用的功能叫作同步。所有的資源訪問都是需要同步。

  在dlm中把資源分成了兩大類。分別叫作PCM RESOURCE (cache fusion resource)AND NON-PCM RESOURCE(non-cache fusion resource)。

cache fusion resource特指數據塊資源。非數據塊資源全部歸爲NON-cache fusion resource,包括數據文件,控制文件,數據字典視圖,Librarycache 、row cache等

 

dlm提供的鎖分爲兩種:PCMLOCK AND NON-PCM LOCK 。加上 lock 和latch,在rac數據庫中共有兩大類4種鎖。

Global locks:用於集羣間的併發控制,由 後臺進程使用

Pcm locks

Non -pcm locks

 

local locks:用於本地進程間的併發控制,由用戶進程和後臺進程使用

Locks

   Latch

 

GRD中記錄PCM lock的信息它位於每個實例的SGA中 但每個實例都僅含部分GRD、所有實例的GRD彙總在一起纔是一個完整的GRD
          
    PCM lock有3個主要屬性:Mode、Role、PI

① Mode
 --S
 --X
 --NULL
 對於S,X兩種鎖模式這裏不再贅述
 而NULL代表對應的內存空間可以被重用、在沒有被重用之前、實例是不能訪問這裏的數據
               
 ② Role
 Role這個屬性是用來描述“髒塊”在集羣間的分佈狀況
 注意,“髒”只是用來描述數據塊的內存版本和磁盤版本是否一致、和事務沒有關係
 Role有兩個取值:Local和Global

  對於Local Role、Mode只會是S或X:
   Ⅰ 如果Mode是S,則該數據塊內存版本和磁盤版本一致
   Ⅱ 如果Mode是X, 則該數據塊內存版本和磁盤版本不同
      當擁有LocalRole和X Mode的實例給其他實例發送數據塊:
   Ⅰ 如果接收方收到的也是和磁盤一致的版本的,那麼本實例(發送方)仍然保持Local Role

 Ⅱ 如果接收方收到的和磁盤版本不一致,那麼發送方和接收方的角色就要轉換成Global


               對於Global RoleMode可以是SX、或NULL
               
               Global Role意味着一個“髒塊”同時被多個實例擁有
               如果想要把這個“髒塊”flush到磁盤,必須要聯繫GRD,讓擁有該塊Current版本的實例完成寫動作
               但對於擁有LocalRole的實例而言,如果要把“髒塊”flush到磁盤,不需要聯繫GRD,由本實例完成即可      
                
            ③ Past Image
               
              下面通過例子說明什麼是PastImage
              假設一個2節點的RAC集羣,塊_A在磁盤上的SCN=1
              1)node1要修改塊_A,從磁盤讀入SGA進行修改,修改後塊_A在內存中的SCN=2
              2)node2也要修改塊_A,node1就會通過cachefusion把塊_A傳送給node2,傳的是SCN=2的版本,
                即Currentcopy的數據塊,這時node1還是會保留這個SCN=2的塊在SGA中,但是不能再進行任何修改
                這時node1擁有的這個Image就叫做“PastImage”
                在node1發送Currentcopy之前,會先把相應的redoentry flush到redolog
              3)node2修改這個數據塊,修改後SCN=3,但磁盤的版本仍然是SCN=1
              4)如果node1發生檢查點事件,因爲node1上塊_A是“髒塊”,所以塊_A必須被同步到磁盤
              5)node1會聯繫GRD,發現node2擁有塊_A的Current版本,GRD會通知node2把這個塊寫入磁盤
              6)node2完成寫之後,會通知所有擁有PI版本的實例釋放他們所擁有的PI內存。這是node1會在logbuffer中記錄一條BWR記錄,然後釋放pi內存。

         7)假設node2沒有完成寫時就異常宕機,這時就會觸發node1進行crashrecovery。雖然之前的修改動作被記錄在各個節點的聯機日誌中,但是因爲node1擁有最近的PI,所有隻需要利用實例1的PI和node2的聯機日誌就可以完成恢復。

所以,pastimage 代表着這個實例的sga中是否擁有和磁盤內容不一致的版本,以及版本順序,並不是代表這個節點是否曾經修改過這個數據塊,pastimage主要能夠加速crashrecovery的恢復過程。

 

 

接下來,我們通過下面的的例子說明在RAC 數據庫中訪問某個block時會發生什麼事情。

1. 
節點C要求讀取塊1008



11008塊的主節點被hashD節點,之後節點C向主節點發送請求,要求以S模式鎖定塊1008。這時buffer lock的模式是SL0S?hared L?local, 0?沒有PI)。

2
)主節點把對應的鎖賦予節點C

3
)節點C 從數據文件中讀取塊108

4
)讀取完成,節點C 獲得對應的鎖,屬性爲SL0



2.節點B要求讀取塊1008



1 節點B向主節點D發出請求,要求以S模式鎖定塊1008

2
 主節點D發現節點C已經以S模式獲得了對應的鎖,而且S鎖之間是可兼容的,所以,不需要鎖的轉換,主節點D要求實例C發送塊1008 給實例B

3
 節點C發送對應的塊給節點B

4
 節點B通知主節點D,已經獲得了塊1008上的S 鎖,屬性爲SL0



3.節點B要求修改塊1008 中的信息。



1) 節點B向主節點D發出請求,要求以X模式鎖定塊1008

2) 
主節點D發現節點C已經以S模式獲得了對應的鎖,而且S鎖於X鎖之間是不兼容的,所以,需要鎖的轉換,主節點D要求節點C將對應的鎖級別降低爲N,所得屬性爲NL0

3) 
節點B將自己的所降級,並且將本地的塊1008 標識爲CR。之後,節點B將塊1008 修改爲塊1009,同時將通知主節點鎖的屬性爲XL0

4
.節點A要求修改塊1009

 1 節點A向主節點D發出請求,要求以X模式鎖定塊1009

2
 節點D發現節點B已經以X模式持有了對應的鎖,而且X模式的鎖是不能兼容的,所以,主節點D 要求節點B降級鎖到N模式,同時由於塊在節點AB都被修改,所以,鎖的角色變爲全局(Global,而且節點B上的塊會變成一個PI。也就是說這時,節點B上的鎖的屬性爲NG1(模式—> N, 角色—>G, 存在PI—>1)。

3
 節點B完成鎖的降級之後,把塊1009傳遞給節點A

4
 節點A修改塊1009 1013,同時將自己節點的鎖設置爲XG0,並且通知主節點。



5. 節點C 查詢塊1013



1 節點C發送請求給主節點D,要求以S模式鎖定塊1013.

2
 主節點發現節點A擁有最新的塊1013,而且這個節點以X模式鎖定了這個塊,因爲XS鎖是不兼容的,主節點發送請求給節點A,要求降級鎖。

3
 節點A降級鎖爲S模式,同時,由於最新的塊會發送給節點C,所以在節點A上的塊1013變爲PI。接下來,節點A把塊1013發送給節點C。這是節點A上的鎖爲SG1

4
 節點C收到最新的塊1013,並且以S模式鎖定塊,並把自己的鎖更新爲SG0。最後,通知主節點D



根據以上的說明,我們能夠看到,對於RAC系統,當一個進程需要訪問一個塊時,一定要首先獲得塊上對應的鎖,之後才能對塊進行相應的操作。而且,在RAC系統中,無論數據庫包含多少個節點,當訪問一個buffer時,最多會有3個節點參與其中,他們是主節點,持有者節點和申請者節點。而且,每一次訪問的時候,都要有消息在節點間不斷的傳遞。另外,我們能看到,如果鎖的角色是全局,那麼我們要做的事情更多,也意味着我們要訪問的代碼深度也越多。這也從一個角度解釋了爲什麼oracle 會在RAC中推出DRMread mostlyreader bypass等新特性(關於後兩個新特性,我們會在今後的文章介紹)。


最後,對於PCM lock,以上過程都是由 lms進程完成的。而對於enqueue,是由lmdj進程完成的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章