O_DIRECT參數詳解


Linux設備IO研究與mysql性能調優關系

本篇文章主要是教大家如何在Linux系統里對數據庫及設備IO庫進行調優,相信對於Linux的初學者來說會有很大的幫助!
  數據庫系統是基於文件系統的,其性能和設備讀寫的機制有密切的關系。和數據庫性能密切相關的文件I/O操作的三個操作:
  open 打開文件
  write 寫文件
  fdatasync flush操作(將文件緩存刷到磁盤上)。
  一、Open操作
  open("test.file",O_WRONLY|O_APPDENT|O_SYNC))
  系統調用Open會為該進程一個文件描述符fd。這里使用了O_WRONLY|O_APPDENT|O_SYNC打開文件:
  1. O_WRONLY表示我們以"寫"的方式打開,告訴內核我們需要向文件中寫入數據;
  2. O_APPDENT告訴內核以"追加"的方式寫文件;
  3. O_DSYNC告訴內核,當向文件寫入數據的時候,只有當數據寫到了磁盤時,寫入操作才算完成(write才返回成功)。
  4. 和O_DSYNC同類的文件標志,還有O_SYNC,O_RSYNC,O_DIRECT。
  (1) O_SYNC比O_DSYNC更嚴格,不僅要求數據已經寫到了磁盤,而且對應的數據文件的屬性(例如文件長度等)也需要更新完成才算write操作成功。可見O_SYNC較之O_DSYNC要多做一些操作。
  (2) O_RSYNC表示文件讀取時,該文件的OS cache必須已經全部flush到磁盤了;
  (3) 如果使用O_DIRECT打開文件,則讀/寫操作都會跳過OS cache,直接在device(disk)上讀/寫。因為沒有了OS cache,所以會O_DIRECT降低文件的順序讀寫的效率。
  二、Write操作
  write(fd,buf,6)
  在使用open打開文件獲得文件描述符之后,我們就可以調用write函數來寫入數據了,write會根據前面的open參數不同,而表現不同。
  三、Flush階段
  fdatasync(fd) == -1
  write操作后,我們還調用了fdatasync來確保文件數據flush到了disk上。fdatasync返回成功后,那么可以認為數據已經寫到了磁盤上。像這樣的flush的函數還有fsync、sync。
  1. Fsync和fdatasync的區別等同於O_SYNC和O_DSYNC的區別。
  2. Sync函數表示將文件在OS cache中的數據排入寫隊列,並不確認是否真的寫磁盤了,所以sync並不可以靠。
  忽略文件打開的過程,通常我們會說“寫文件”有兩個階段,一個是調用write我們稱為寫數據階段(其實是受open的參數影響),調用fsync(或者fdatasync)我們稱為flush階段。Linux上的塊設備的操作可以分為兩類:
  第一類是使用C標准庫中的fopen/fread/fwrite 系列的函數,我們可以稱其為 buffered I/O。
  具體的I/O path如下:
  Application<->Library Buffer<->Operation System Cache<->File System/Volume Manager<->Device
  library buffer是標准庫提供的用戶空間的buffer,可以通過setvbuf改變其大小。
  第二類是使用Linux的系統調用的open/read/write 系列的函數,我們可以稱其為 non-buffered I/O。
  Application<-> Operation System Cache <->File System/Volume Manager<->Device
  此外,我們可以通過設置open的O_DIRECT 標志來實現Direct I/O (或者叫Raw I/O ),即繞過OS Cache,直接讀取Device ( that's what we want^o^ ), 等於將OS cache換成自己管理的cache。不過,Linus在郵件列表中建議不這么做,而是使用posix_fadvice, madvice。中表明Direct I/O比buffered I/O的性能高很多。
  在MySQL中,參數Innodb_flush_method(Linux)可以設定為:Fdatasync、O_DSYNC、O_DIRECT。我們看看這個三個參數是如何影響程序MySQL對日志和數據文件的操作:
  Open logFlush logOpen datafileFlush data
  Fdatasync
  fsync()
  fsync()
  O_DSYNCO_SYNC
  fsync()
  O_DIRECT
  fsync()O_DIRECTFsync()
  fdatasync被認為是安全的,因為在MySQL總會調用fsync來flush數據。使用O_DSYNC是有些風險的,有些OS會忽略該參數O_SYNC
  我們看到O_DIRECT和fdatasync和很類似,但是它會使用O_DIRECT 來打開數據文件。有數據表明,如果是大量隨機寫入操作,O_DIRECT 會提升效率。但是順序寫入和讀取效率都會降低。所以使用O_DIRECT需要謹慎。
  mysql innodb 對應相關參數:
  innodb_flush_method有三個值,分別是fdatasync,O_DSYNC和O_DIRECT,其中fdatasync是默認值。
  它們控制了InnoDB刷新日志和數據的模式。
  fdatasync:InnoDB使用fsync()函數去更新日志和數據文件。
  O_DSYNC:InnoDB使用O_SYNC模式打開並更新日志文件,用fsync()函數去更新數據文件。
  O_DIRECT:InnoDB使用O_DIRECT模式打開數據文件,用fsync()函數去更新日志和數據文件。

  我們看到O_DIRECT和fdatasync和很類似,但是它會使用O_DIRECT 來打開數據文件。有數據表明,如果是大量隨機寫入操作,O_DIRECT 會提升效率。但是順序寫入和讀取效率都會降低。所以使用O_DIRECT需要謹慎。

 可選取值有Fdatasync, O_DSYNC, O_DIRECT

  • *Fdatasync
    調用open(“./ib_logfile0”, …),不設置O_SYNC, 但調用fsync()
    調用open(“./ibdata1”, …),不設置O_SYNC, 但調用fsync()
  • *O_DSYNC,
    調用open(“./ib_logfile0”, …),設置O_SYNC, 不調用fsync()
    調用open(“./ibdata1”, …),不設置O_SYNC,但調用fsync()
  • *O_DIRECT
    調用open(“./ib_logfile0”, …),不設置O_DIRECT, 調用fsync()
    調用open(“./ibdata1”, …),設置O_DIRECT,調用fsync()

 

來自it專家網:http://linux.ctocio.com.cn/274/12586274.shtml

 

MySQL如何避免使用swap

 

Linux有很多很好的內存、IO調度機制,但是並不會適用於所有場景。對於DBA來說Linux比較讓人頭疼的一個地方是,它不會因為MySQL很重要就避免將分配給MySQL的地址空間映射到swap上。對於頻繁進行讀寫操作的系統而言,數據看似在內存而實際上在磁盤是非常糟糕的,響應時間的增長很可能直接拖垮整個系統。這篇blog主要講講我們作為DBA,怎樣盡量避免MySQL慘遭swap的毒手。

首先我們要了解點基礎的東西,比如說為什么會產生swap。假設我們的物理內存是16G,swap是4G。如果MySQL本身已經占用了12G物理內存,而同時其他程序或者系統模塊又需要6G內存,這時候操作系統就可能把MySQL所擁有的一部分地址空間映射到swap上去。

cp一個大文件,或用mysqldump導出一個很大的數據庫的時候,文件系統往往會向Linux申請大量的內存作為cache,一不小心就會導致L使用swap。這個情景比較常見,以下是最簡單的三個調整方法:
1、/proc/sys/vm/swappiness的內容改成0(臨時),/etc/sysctl.conf上添加vm.swappiness=0(永久)
這個參數決定了Linux是傾向於使用swap,還是傾向於釋放文件系統cache。在內存緊張的情況下,數值越低越傾向於釋放文件系統cache。
當然,這個參數只能減少使用swap的概率,並不能避免Linux使用swap。
2、修改MySQL的配置參數innodb_flush_method,開啟O_DIRECT模式。
這種情況下,InnoDB的buffer pool會直接繞過文件系統cache來訪問磁盤,但是redo log依舊會使用文件系統cache。值得注意的是,Redo log是覆寫模式的,即使使用了文件系統的cache,也不會占用太多。
3、添加MySQL的配置參數memlock
這個參數會強迫mysqld進程的地址空間一直被鎖定在物理內存上,對於os來說是非常霸道的一個要求。必須要用root帳號來啟動MySQL才能生效。

還有一個比較復雜的方法,指定MySQL使用大頁內存(Large Page)。Linux上的大頁內存是不會被換出物理內存的,和memlock有異曲同工之妙。具體的配置方法可以參考:http://harrison-fisk.blogspot.com/2009/01/enabling-innodb-large-pages-on-linux.html

來自:http://www.taobaodba.com/html/552_mysql_avoid_swap.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM