(轉)innodb_doublewrite_file

denniswwh發表於2011-05-29

原文:

記得剛開始看InnoDB文件的時候,Double Write一節(其實只有一小段)就讓我很困惑。無奈當時內力太淺,糾纏了很久也沒弄明白。時隔幾個月,重新來整理一下。

涉及到的概念:簡稱BP,,,,innodb tablespace

1. 什麼是Double Write

在InnoDB將BP中的Dirty Page刷(flush)到磁碟上時,首先會將Page刷到InnoDB tablespace的一個區域中,我們稱該區域為Double write Buffer。在向Double write Buffer寫入成功後,再擇機將資料複製到正在的資料檔案對應的位置。

咋一看,這個過程有些多餘

[@more@]

2. 為什麼需要Double Write

InnoDB中有記錄(Row)被更新時,先將其在Buffer Pool(簡稱BP)中的page更新,並將這次更新記錄到Log file中,這時候BP中的該page就是被標記為Dirty。在適當的時候(BP不夠、系統閒置等),這些Dirty Page會被flush到磁碟上。

試想,在某個Dirty Page(一般是16K)flush的過程中,發生了系統斷電(或者OS崩潰),16K的資料只有8K被寫到磁碟上,這種現象被稱為(partial page writes、torn pages、fractured writes)。一旦partial page writes發生,那麼在InnoDB恢復時就很尷尬:在InnoDB的Log file中雖然知道這個資料頁被修改了,但是卻無法知道這個頁被修改到什麼程度,和這個頁面相關的redo也就無法應用了。

舉個例子:在InnoDB的log file中有如下Log:

Log sequence number 0 4285149977
Log sequence number 0 4287355447
Log sequence number 0 4289260680
Log sequence number 0 4291279900
Log sequence number 0 4293359020

其中第1、3個Log修改了該page,但是在斷電時,BP中該page只被flush了一部分。那麼InnoDB是無法決定上面的Log是否應該被應用的。這時,資料就出現了不一致。

所以,Log file的有效應用,前提是InnoDB的資料檔案中的Page是一致的。

簡而言之,Double write就是為了避免Partial page writes而設計的。

3. Double Write對效能的影響

系統需要將資料寫兩份,一般認為,Double Write是會降低系統效能的。peter猜測可能會有5-10%的效能損失,但是因為實現了資料的一致,是值得的。認為這應該是儲存層面應該解決的問題,放在資料庫層面無疑是犧牲了很多效能的。

事實上,Double Write對效能影響並沒有你想象(寫兩遍效能應該降低了50%吧?)的那麼大。在BP中一次性往往會有很多的Dirty Page同時被flush,Double Write則把這些寫操作,由隨機寫轉化為了順序寫。而在Double Write的第二個階段,因為Double Write Buffer中積累了很多Dirty Page,所以向真正的資料檔案中寫資料的時候,可能有很多寫操作可以合併,這樣有可能會降低Fsync的呼叫次數。

基於上面的原因,Double Write並沒有想象的那麼糟。另外,Dimitri在測試後,發現開啟和關閉Double Write對效率的影響並不大。

4. 相關引數與狀態

是否開啟了double write:

root@(none) 07:16:16>show variables like "%double%"; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | innodb_doublewrite | ON | +--------------------+-------+

Double write的使用情況:

root@(none) 07:15:50>SHOW STATUS LIKE "%innodb_dblwr%"; +----------------------------+-----------+ | Variable_name | Value | +----------------------------+-----------+ | Innodb_dblwr_pages_written | 145373349 | | Innodb_dblwr_writes | 2249336 | +----------------------------+-----------+

上面可以看到,從BP共Flush了145373349個Pages到double write buffer中;一共呼叫了2249336次write寫到真正的資料檔案。可見,相當於每次write合併了 145373349 / 2249336 = 64.6次Flush。(這就是為什麼double write buffer為什麼並不會對效率有很大影響的原因)

5. 我的看法

在某些檔案系統(ZFS等)層面能夠保證不出現Partial page writes時,可以關閉Double Write。因為它對效能影響並不大,一般情況都建議開啟,畢竟帶來的資料安全性保障可能是我們更關心的。

參考文獻:

[0]. Manual about Double Write

[1]. Innodb Double Write

[2].

[3]. MySQL Performance: InnoDB Doublewrite Buffer Impact

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

相關文章