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 就認為寫入成功(所以這個很不可靠,但效能確實提高啦)
本欄目更多精彩內容:http://www.bianceng.cn/database/MySQL/
對於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()