https://www.cnblogs.com/allegro/archive/2011/04/18/2019598.html
1 理解Linux文件系统挂载参数noatime nodiratime
很多线上服务器为了提供文件系统IO性能,会在挂载文件系统的时候指定“noatime,nodiratime”参数,意味着当访问一个文件和目录的时候,access time都不会更新。但是如果未指定上面的参数,atime则会更新。那么具体差异在哪里?
$ 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"的情况下
$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"的情况下
在平日里经常有删除文件的需求,大概如下
删除过去N天内都未访问过的文件或者目录(删除N天前访问过的文件)
$ #注意这条命令很危险!
$ find /home/fire/ -atime +N -exec rm -rf {} \;
假设 /home/fire 目录是一周之前创建的,那么对于这条命令有两个执行结果
$ #注意这条命令很危险!
$ find /home/fire/ -atime +7 -exec rm -rf {} \;
看了上面的例子会发现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。