1. 程式人生 > >我的oracle筆記-01 之 MVCC協議

我的oracle筆記-01 之 MVCC協議

好吧,現在做迴文藝青年。

我決定把自己對ORACLE MVCC的瞭解分享出來,畢竟前期折騰了這麼長時間,現在算是利用一下剩餘價值吧。其實你如果要做一些多使用者環境下的資料管理,資料庫中的許多技術都值得你去借鑑,儘管你不一定需要ACIDMVCC就是這樣一種技術,它可以在保證資料一致性的同時,實現最大的併發。其實我覺得ORACLE中最有價值的就是MVCCRAC,至於其它的,都屬於“強者更強”的自然發展吧。

試圖用最直白的自然語言把MVCC說清楚,對我來說可不是一件容易的事情,但我仍然對當年研究DSI時的痛苦記憶尤深,希望我的介紹對大家有所幫助,畢竟DSI是寫給SUPPORT看的,更多的時候,它只是告訴你How

,而不是Why

從協議上看,MVCC很簡單,就是你總是隻能看到資料庫在某個時間點的狀態(ReadConsistencyRC),而不管其後那些資料是否發生了更新,所以實際上你是看到了資料的某個歷史版本,在ORACLE中,這個點就是你(事務)開始的時間,這樣我們就實現了所謂的讀寫並行,也就是你的讀總是能成功(而且你每次讀到的都是同一個資料),即使資料正在被人更新(因為你們其實操作的是不同的版本)。

然而任何好處都必須有代價,不是嗎。你所付出的代價就是所謂的寫寫序列,沒錯,寫被嚴格串行了,記住,儘管你可以讀取資料的任意歷史版本,但寫只會作用於資料的當前版本,或者叫最新版本。所謂寫寫序列,就是說如果在你開始事務和寫資料之間,資料已經被其它人改了,或者說得準確點,當你看到的版本不是當前版本時,You Are Killed

(事務回滾)。所以你會注意到,ORACLE本質上並不適合於寫寫衝突劇烈的應用(聽到這,DB2笑了)。

為了更準確地描述協議,我們需要引入一個關於時間點的術語,SCN,關於SCN,有人叫它SystemChange Number,也有人叫System Commit Number,好吧,我並不在意這個。SCN機就是一種時間序,系統會維護一個GlobalSCN表示當前的時間,每個事務開始時(嚴格地說,是你開始發出第一條SQL時),你會獲得當前時間,那就是你能夠看到的時間,ORACLE中,這個時間叫做快照時間(SnapshotSCN),也就是說,就好像你在這個時候給資料庫排了個快照。當事務提交的時候,你會獲取當前時間並把GlobalSCN+1

,這個時間叫做提交時間(CommitSCN)。當你更新資料時,你會產生一個新的版本,並把你的CommitSCN賦給這個版本(注意這裡的語病,實際上這時候你還沒有拿到CommitSCN,好吧,這個問題我們以後再說)。

所以事務有快照SCN和提交SCN,資料也有SCN,接下來我們可以準確地定義ORACLEMVCC

關於讀,你能夠看到這個資料,如果:

1)它是你自己的更新,或者

2)它是已經提交的資料,並且SCN <=你的SnapshotSCN

關於寫,你能夠更新這個資料,如果:

1)它是最新的,並且

2.1)它是你自己的更新,或者

2.2)它是已提交的資料,並且SCN <=你的SnapshotSCN

前面說到,在關於寫寫序列中,如果你看到的版本不是當前版本,你會被Killed。好吧,我承認這樣說對ORACLE不公平,事實上有兩點:1)如果當前版本尚未提交,那麼你可以等待,如果那個事務最後回滾了,那麼你有很大的機會能過關。2ORACLE實際上定義了兩個時間點,或者說兩種隔離級別,一種是事務級RC,也就是你只能看到本事務開始時資料庫的狀態,另一種是語句級RC,你只能看到本條語句開始時資料庫的狀態,在語句級RC中,在你被Killed之前,你可以重啟當前語句,於是你便獲得了一個更大的SnapshotSCN(比那個資料的SCN更大),然後再試一次,你過關了。

所以感謝上帝,在ORACLE中,除非你特別指定,否則你總是在語句級RC中幸福地徜徉,因此只要你願意不斷地去重試(如果我們不去考慮重啟的代價),事實上我們就實現了一種理論上最佳的併發協議,事務永不Killed

但是現實總是殘酷的,再好的協議,落地的時候總是會.....

好吧,先說到這吧,我得準備下週一和使用者交流的PPT去了,這周看來是沒什麼時間了。

轉載自:http://blog.sina.com.cn/s/blog_d3bf72ff0101nrhy.html