关于 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。