關於 mount掛載時候的參數 noatime nodiratime 的一些說明
- 2019 年 10 月 4 日
- 筆記
以下內容來自2篇部落格,地址分別是:
http://www.firefoxbug.com/index.php/archives/2801/
https://www.cnblogs.com/allegro/archive/2011/04/18/2019598.html
1 理解Linux文件系統掛載參數noatime nodiratime
很多線上伺服器為了提供文件系統IO性能,會在掛載文件系統的時候指定「noatime,nodiratime」參數,意味著當訪問一個文件和目錄的時候,access time都不會更新。但是如果未指定上面的參數,atime則會更新。那麼具體差異在哪裡?
未指定 noatime,nodiratime
$ touch test ; stat test ; ... Access: 2015-04-04 00:37:23.507135507 +0800 Modify: 2015-04-04 00:37:23.507135507 +0800 Change: 2015-04-04 00:37:23.507135507 +0800 $ echo hello >> test ; stat test; ... Access: 2015-04-04 00:37:23.507135507 +0800 Modify: 2015-04-04 00:37:38.018430637 +0800 Change: 2015-04-04 00:37:38.018430637 +0800 $ cat test ;stat test ... Access: 2015-04-04 00:38:02.916135510 +0800 Modify: 2015-04-04 00:37:38.018430637 +0800 Change: 2015-04-04 00:37:38.018430637 +0800
可以看出未指定"noatime,nodiratime"的情況下
- read文件的時候會導致atime更新,不會導致mtime和ctime更新
- write文件只會導致mtime和ctime更新,不會導致atime更新。
指定 noatime,nodiratime
$touch test ; stat test ; ... Access: 2015-04-04 00:28:28.680135484 +0800 Modify: 2015-04-04 00:28:28.680135484 +0800 Change: 2015-04-04 00:28:28.680135484 +0800 $ sleep 10 ; echo hello >> test ; stat test; ... Access: 2015-04-04 00:28:28.680135484 +0800 Modify: 2015-04-04 00:28:38.682727983 +0800 Change: 2015-04-04 00:28:38.682727983 +0800 $ cat test ;stat test ... Access: 2015-04-04 00:28:28.680135484 +0800 Modify: 2015-04-04 00:28:38.682727983 +0800 Change: 2015-04-04 00:28:38.682727983 +0800
可以看出指定"noatime,nodiratime"的情況下
- read文件的時候不會導致atime、mtime、ctime改變
- write文件只會導致mtime和ctime更新,不會導致atime更新。
實際應用場景
在平日里經常有刪除文件的需求,大概如下
刪除過去N天內都未訪問過的文件或者目錄(刪除N天前訪問過的文件) $ #注意這條命令很危險! $ find /home/fire/ -atime +N -exec rm -rf {} ;
假設 /home/fire 目錄是一周之前創建的,那麼對於這條命令有兩個執行結果
$ #注意這條命令很危險! $ find /home/fire/ -atime +7 -exec rm -rf {} ;
- 指定"noatime":find的時候發現 /home/fire 是7天之前創建的,立馬就會刪除整個目錄。而且還會報錯"find: /home/fire: No such file or directory",原因就是第一個rm -rf /home/fire 之後 find失敗了。這種是很危險的!原因是會誤刪除文件。
- 未指定"noatime":那就得看情況,如果/home/fire過去7天沒有被訪問過,那麼就和情況一一樣,直接刪除。如果過去7天內,該目錄有人訪問過,atime肯定是7天之內,那麼就會遍歷下面的目錄,依次按照之前邏輯。但是遍歷過程會更改目錄的atime。
看了上面的例子會發現find去刪除目錄的時候變得好複雜,而且一定要小心。所以find刪除更適用於刪除文件,不要刪除目錄。
刪除N天內未被訪問過的文件 $ find /home/fire/ -atime +N -type f -exec rm -f {} ;
2 我們需要同時設置noatime和nodiratime嗎?很多資料都提到要同時設置noatime和nodiratime,但我們看mount(2)關於參數的描述:
MS_NOATIME Do not update access times for (all types of) files on this file system. MS_NODIRATIME Do not update access times for directories on this file system. This flag provides a subset of the functionality provided by MS_NOATIME; that is, MS_NOATIME implies MS_NODIRATIME.
如何理解這裡的「(all types of) files」,目錄是否作為文件的一類?
還是看看內核源碼的相關內容,在文件fs/inode.c中有個touch_atime函數:
void touch_atime(struct vfsmount *mnt, struct dentry *dentry) { /* ... */ if (inode->i_flags & S_NOATIME) return; if (IS_NOATIME(inode)) return; if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) return;
可以看到,一旦NOATIME標誌位設置,NODIRATIME就不再被處理了。
而且Andrew Morton同學也說了:"noatime is a superset of nodiratime, btw."
好了,大家知道該怎麼做了吧。
結論: mount掛載的時候,只用 noatime即可,不用加 nodiratime。