conv的參數有
1.sync
Pad every input block to size of 'ibs' with trailing zero bytes. When used with 'block' or 'unblock', pad with spaces instead of zero bytes.
2.fdatasync
Synchronize output data just before finishing. This forces a physical write of output data.
3.fsync
Synchronize output data and metadata just before finishing.This forces a physical write of output data and metadata.
flag的參數有
flag分為oflag和iflag
1.direct
2.dsync
Use synchronized I/O for data. For the output file, this forces a physical write of output data on each write. For the input file, this flag can matter when reading from a remote file that has been written to synchronously by some other process. Metadata (e.g., last-access and last-modified time) is not necessarily synchronized.
3.sync
Use synchronized I/O for both data and metadata.
dsync跟sync比較好理解,前者是只同步寫數據,sync同時寫數據和元數據
但是感覺dsync與 -fsync怎么感覺有些一樣? 網上的說法是 dd if=/dev/zero of=test bs=64k count=4k oflag=dsync 這個可以當成是模擬數據庫插入操作,所以很慢,但還是沒太明白。
后來自己認真的摳了這英文用詞, conv=fsync Synchronize output data and metadata just before finishing 意思也就是在dd命令結束前同步data和metadata,那就是不是每一次寫都同步一次咯,也就是如果我們在dd命令中寫了100次,他可能是等到最后的時候才把他們同步到磁盤。而oflag=dsync是說Use synchronized
I/O for data. For the output file, this forces a physical write of output data on each write,注意這里邊用詞 a physical write of output data on each write,那就是他是每一次寫都得等到這一次寫寫到了磁盤才進行下一個寫,也就是如果我們使用dd寫100次,他每次寫都是寫到磁盤后才進行下一次寫的。所以這樣當然要比conv=fsync慢一些吧。那么自己感覺如果只是寫一次的話,兩者應該是差別不大的,后來做了下小實驗,證實確實是這樣的。
在第一個圖中,我們只寫1塊,然后使用oflag=sync與conv=fsync 測出來一個是32.1kb/s 一個是37.8kb/s 差別不大。但是下一個我寫1000個,conv=fsync就明顯的比oflag=dsync/sync快很多了,所以覺得上面自己扣的英文的理解應該是正確的。
所以在用dd做讀或者寫的時候,應該要注意自己的使用場景,如果需要將數據寫入磁盤的話
dd if=/dev/zero of=test bs=64k count=16k 是不准確的,
而 dd if=/dev/zero of=test bs=64k count=16k conv=fsync 比較准備,他在dd結束前會寫到磁盤,
而dd if=/dev/zero of=test bs=64k count=4k oflag=dsync或者sync 是真正的每寫一次就寫一次磁盤,所以其實可以聽到磁盤啪啪啪的響的。
dd如何繞開cache
如果要規避掉文件系統cache,直接讀寫,不使用buffer cache,需做這樣的設置
iflag=direct,nonblock
oflag=direct,nonblock
iflag=cio
oflag=cio
direct 模式就是把寫入請求直接封裝成io 指令發到磁盤
非direct 模式,就把數據寫入系統緩存,然后就認為io 成功,並由操作系統決定緩存中的數據什么時候被寫入磁盤
$ dd if=/dev/zero of=test bs=64k count=4k oflag=dsync 記錄了4096+0 的讀入 記錄了4096+0 的寫出 268435456字節(268 MB)已復制,48.6814 秒,5.5 MB/秒
$ dd if=/dev/zero of=test bs=8k count=256k conv=fdatasync 記錄了262144+0 的讀入 記錄了262144+0 的寫出 2147483648字節(2.1 GB)已復制,41.277 秒,52.0 MB/秒
我們會發現第一行命令執行完,僅生成了 268 MB 的數據,用時卻長達 48+ 秒。
而第二行命令執行完,雖然生成了 2.1GB 的數據,比第一行命令生成的數據大的多,但是用時卻只有 41+ 秒,反而用時少。
為什么呢?
請注意下 oflag=dsync 參數,這個參數表明每當需要寫數據時都會真正到寫到磁盤上,等寫到磁盤上之后,才會繼續開始下一次數據寫入。第一行命令要求反復寫 4k 次數據,也就是說,會真正寫磁盤 4k 次,用時長是理所當然的。
而第二行命令,雖然總共要寫 2.1 GB 的數據,但是由於使用的是 conv=fdatasync 參數,也就是說,當 dd 命令結束前,一次性把所有的數據寫到磁盤上,因此寫入速度非常快。
我們再做一個測試,還是使用上面兩個命令,參數相同,不同的僅是 count 參數設置為 1,bs 設置為 256 MB。那么根據之前的說明,我們可以推測,兩次測試的結果應該是相近的。
$ dd if=/dev/zero of=test bs=256MB count=1 oflag=dsync 記錄了1+0 的讀入 記錄了1+0 的寫出 256000000字節(256 MB)已復制,3.85186 秒,66.5 MB/秒
$ dd if=/dev/zero of=test bs=256MB count=1 conv=fdatasync 記錄了1+0 的讀入 記錄了1+0 的寫出 256000000字節(256 MB)已復制,4.23802 秒,60.4 MB/秒