MySQL的double write和Oracle對比學習

jeanron100發表於2015-02-15
之前有網友希望我對mysql的double write和oracle能夠做一個對比,其實這種對比方式挺好,能夠觸類旁通,舉一反三。不過限於本人水平有限,歡迎拍磚。
關於MySQL的double write是對partilal write的一個補充。比如將資料寫入磁碟的時候,發生了斷電情況,那麼一部分內容寫入一部分就丟失了,這個時候使用redo log來恢復就不可行了,因為從日誌檔案層面資料的變更已經是不完整的了。


double write的大體是這樣的。部分內容參考了連結 http://www.cnblogs.com/benshan/archive/2013/01/14/2859336.html
double write分為兩部分,一部分是doublewrite buffer,大小為2M,另外一部分就是物理磁碟上的共享表空間中連續的128個頁,即兩個區,大小同樣為2M。當緩衝池的脹業重新整理時,並不直接寫硬 盤,而是透過memcpy函式將髒頁先複製到記憶體中的doublewrite buffer,之後透過doublewrite buffer再分兩次寫,每次寫入1M到共享表空間的物理磁碟上,然後馬上呼叫fsync函式,同步磁碟。

這個問題可以簡單的歸結為innodb恢復的原理,從這個層面來說和oracle還是存在著很大的不同。
首先double write是限於Innodb 儲存引擎的,而且是作為一個可選的方案,透過引數InnoDB_doublewrite的值來控制,如果為0表示不啟用,可以透過show status like  "%InnoDB_dblwr%"來檢視。
既然作為可選方案,肯定是有一定的原因,就是出於效能的考慮,位於共享表空間的double write buffer其實也是檔案,寫double write buffer本身也會有fsync操作,只是double write寫入的過程是一個順序寫的過程,所以對效能降低不會太低。

oracle的恢復機制相比double wriite更加靈活和全面。
首先oracle中採用了undo+redo機制來作為資料恢復的基石,資料的恢復是透過前後臺結合來實現的,在快取級別,存在dbwr,能夠把修改後的資料塊刷入資料檔案,這是一個非同步的過程,不會因為發生資料變更就馬上寫入資料檔案,同時存在log buffer,能夠透過log buffer生成redo日誌,最後透過lgwr把這部分變更刷到redo 日誌,在這個過程中lgwr負責了保持資料完整性的任務,保證了資料在任何情況下都不會丟失。
上面的操作,寫入資料檔案的過程不是實時的,可以存在一定的延時,所以重點就放在了redo日誌上面,在備份恢復方面還是最重要的。
如果在dbwr把資料變更的資料塊寫入資料檔案的時候,如果發生斷電的情況,當例項重新啟動的時候,oracle會根據redo 日誌構造出變更前的資料塊資訊,從而完成了前滾,把丟失的資料塊找回來。這樣資料庫就恢復為了奔潰前的狀態,如果某些事務沒有提交或者回滾,又會繼續做一個回滾操作。這個過程會透過smon來結合Undo來實現。
從整個過程來說,oracle支援的面很廣,就如Oracle所承諾的那樣,做了commit的資料就能夠恢復。從IO消耗的角度來看,物理IO的消耗就在於重新整理資料到資料檔案,資料變更寫入redo,沒有額外的物理IO。

結合MySQL來看,double write buffer扮演的角色有點類似 log buffer的作用。因為oracle已經開闢了log buffer的快取空間,所以快取級的IO還是很快的,double write buffer就會存在部分的物理IO操作。
不過從技術的架構和角度來看,不能完全說出某一種好還是不好,從目前的分析來看,oracle相比double write還是技高一籌,不過從體系結構上要複雜的多。而且還涉及到更多的細節需要最佳化。

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

相關文章