innodb_flush_log_at_trx_commit 決定了事務日志何時write,flush
innodb_flush_method确定了日志及資料檔案如何write、flush。“show variables”顯示該變量為空,那說明被設定了預設值(fdatasync)
下面我們先從Linux IO上了解一下檔案是如何打開、寫入、刷寫到磁盤上的。
一般的檔案I/O操作的三個過程open、write、fdatasync,分别是打開檔案、寫檔案、flush操作(将檔案緩存刷到磁盤上)
open 階段:
系統調用Open(),使用 O_WRONLY| O_APPEND|O_SYNC 打開檔案:
O_WRONLY表示我們以“寫”的方式打開檔案。
O_APPDENT以追加的方式寫檔案。
O_DSYNC 當向檔案寫入資料的時候,隻有當資料寫到了磁盤時,寫入操作才會完成(write 才會傳回成功),
與之相對應的是:
O_SYNC: 這個比O_DSYNC 更嚴格,把資料寫入到檔案時,還要把資料的一些元資訊寫入到磁盤比如檔案長度等。
O_RSYNC 表示檔案讀取時,該檔案的緩存必須已經flush到磁盤上。
O_DIRECT打開檔案,則讀/寫操作都會跳過OS cache,直接在device(disk)上讀/寫。(這樣會降低檔案的順序讀寫的效率)
write階段: 依賴與open階段。
flush階段:将資料刷寫到磁盤上。
Fdatasync() 來確定資料檔案flush到了磁盤上。
與之相對應的是:
fsync() fdatasync()兩者差別等同于 O_sync 和 O_Dsync
sync()函數,将檔案寫入os cache 就認為寫入成功(是以這個很不可靠,但性能确實提高啦)
對于linux平台的 innodb_flush_method() 設定為 Fdatasync 預設,O_sync, O_Direct
對于fdatasync:
Innodb 使用fsync()函數來刷寫資料和日志。fysnc()相比fdatasync()函數需要更多的IO(中繼資料資訊),fdatasync()在某些情況下造成Innodb崩潰。
使用fsync()的缺點是 os會緩存部分資料。因為Innodb 能夠比os更能智能的管理自己的緩存區(Innodb buffer pool)。這樣會造成雙緩沖的浪費。(雙緩沖部分的優點:有些檔案系統會累計寫入并執行他們,可能很有效率的排序,或者并行的寫入到裝置中。可以做預讀取),具體情況可以具體測試一番。如果啟用Innodb_file_per_table時導緻每個檔案都被單獨使用fsync()函數,,當寫入到多個表的時候不能合并到單個IO操作中。http://blog.51cto.com/user_index.php
對于O_DIRECT:
資料檔案使用該标記,這個選項不會影響日志檔案,對linux、freeBSD、Solaris 支援。,這個時候os不會緩存資料,完全禁止了os緩存并且使所有的讀寫動作直接到儲存設備(避免了雙緩沖),使用fsync()把檔案刷寫到磁盤上(該設定不能禁止RAID卡上的提前讀取功能,隻是禁止os的提前讀取功能),對于RAID卡的緩存還是建議打開的。對于Innodb_file_per_table影響不大(熱身時間會加長,滿足buffer pool)
對于O_DSYNC:
這個對日志檔案調用open()使用了O_SYNC标志,所有的寫入是同步的,資料隻有寫入磁盤才算有效。它不會影響資料檔案。
它不會禁止os 的緩存.
具體關系:
openlog flush log opendata file flush datafile
Fdatasync fsync() fsync()
O_DSYNC O_SYNC fsync()
O_DIRECT fsync() O_DIRECT fsync()
本文轉自 位鵬飛 51CTO部落格,原文連結:http://blog.51cto.com/weipengfei/985968,如需轉載請自行聯系原作者