理解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"的情况下

  1. read文件的时候会导致atime更新,不会导致mtime和ctime更新
  2. 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"的情况下

  1. read文件的时候不会导致atime、mtime、ctime改变
  2. 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 {} \;

注:

上面是转载的原文,基本没有问题,但关于禁止文件和目录的访问时间,只需指定noatime即可,因为在linux内核中,当指定了noatime,关于nodiratime的判断也就自动跳过了。

下面是最新稳定版linux  4.13.3内核 中关于这段的代码说明:

bool __atime_needs_update(const struct path *path, struct inode *inode,
              bool rcu)
{
    struct vfsmount *mnt = path->mnt;
    struct timespec now;

    if (inode->i_flags & S_NOATIME)
        return false;

    /* Atime updates will likely cause i_uid and i_gid to be written
     * back improprely if their true value is unknown to the vfs.
     */
    if (HAS_UNMAPPED_ID(inode))
        return false;

    if (IS_NOATIME(inode))
        return false;
    if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))
        return false;

    if (mnt->mnt_flags & MNT_NOATIME)
        return false;
    if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
        return false;

    now = current_time(inode);

    if (!relatime_need_update(path, inode, now, rcu))
        return false;

    if (timespec_equal(&inode->i_atime, &now))
        return false;

    return true;
}

生产环境中的Linux内核多没有这么新,一般是2.6.32左右的,下面是2.6.32的linux内核关于这一点的说明:

void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
{
    struct inode *inode = dentry->d_inode;
    struct timespec now;

    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;

    if (mnt->mnt_flags & MNT_NOATIME)
        return;
    if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
        return;

    now = current_fs_time(inode->i_sb);

    if (!relatime_need_update(mnt, inode, now))
        return;

    if (timespec_equal(&inode->i_atime, &now))
        return;

    if (mnt_want_write(mnt))
        return;

    inode->i_atime = now;
    mark_inode_dirty_sync(inode);
    mnt_drop_write(mnt);
}
EXPORT_SYMBOL(touch_atime);

通过查看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_NOAT-
              IME; that is, MS_NOATIME implies MS_NODIRATIME.

MS_RELATIME (Since Linux 2.6.20)
              When a file on this file system is accessed, only update the file’s last access time (atime) if the current value of atime is less  than
              or  equal  to the file’s last modification time (mtime) or last status change time (ctime).  This option is useful for programs, such as
              mutt(1), that need to know when a file has been read since it was last modified.  Since Linux 2.6.30, the kernel defaults to the  behav-
              ior  provided  by  this flag (unless MS_NOATIME was specified), and the MS_STRICTATIME flag is required to obtain traditional semantics.
              In addition, since Linux 2.6.30, the file’s last access time is always updated if it is more than 1 day old.

 MS_STRICTATIME (Since Linux 2.6.30)
              Always update the last access time (atime) when files on this file system are accessed.  (This was the  default  behavior  before  Linux
              2.6.30.)  Specifying this flag overrides the effect of setting the MS_NOATIME and MS_RELATIME flags.

通过判定MS_NODIRATIME,如果为真,就不再更新目录的访问时间。

上面参数中提到了MS_RELATIME,对于某些用户某些应用,atime 信息可能是必要的,比如邮件程序和备份工具。如果完全禁止 atime 更新会使这些程序无法正常工作。针对这种情况,Linux 在内核 2.6.20 中添加了一个新的 mount 选项 relatime(relative atime 的意思)。relatime 的意思是访问文件时,仅在 atime 早于文件的更改时间时对 atime 进行更新。在内核 2.6.24 中,又对 relatime 进行了扩展,在访问文件时,当 atime 已经超过某个时间(例如一天)没有更新,就对 atime 进行更新。这个扩展的意思就是调整 atime 的更新粒度。

下面是mount(8)中的参数说明:

relatime
              Update  inode  access times relative to modify or change time.  Access time is only updated if the previous access time was earlier than
              the current modify or change time. (Similar to noatime, but doesn’t break mutt or other applications that need to know  if  a  file  has
              been read since the last time it was modified.)

              Since  Linux  2.6.30,  the  kernel defaults to the behavior provided by this option (unless noatime was  specified), and the strictatime
              option is required to obtain traditional semantics. In addition, since Linux 2.6.30, the file’s last access time is always  updated   if
              it  is more than 1 day old.

strictatime
              Allows to explicitly requesting full atime updates. This makes it possible for kernel to defaults to relatime or noatime but still allow
              userspace to override it. For more details about the default system mount options see /proc/mounts.

使用 relatime(relative atime)挂载,可在前一个 atime 更新比 mtime 或者 ctime 更新旧时更新 atime。

在这个示例中,GFS2 文件系统位于 /dev/vg01/lvol0,并挂载到目录 /mygfs2。只有在前一个 atime 更新比 mtime 或者 ctime 更新旧时才会进行 atime 更新。

mount /dev/vg01/lvol0 /mygfs2 -o relatime

参考资料:

http://www.firefoxbug.com/index.php/archives/2801/

http://www.cnblogs.com/allegro/archive/2011/04/18/2019598.html

https://mp.weixin.qq.com/s?__biz=MzA3MzYwNjQ3NA==&mid=400742435&idx=1&sn=d5fa0776ebce30be1de897cd7d1eb295&scene=1&srcid=1123K3Ka8EtwjcNXhNfUGJV7#rd

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/fs/inode.c?h=v4.13.3

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/fs/inode.c?h=linux-2.6.32.y

时间: 2024-09-30 10:23:21

理解Linux文件系统挂载参数noatime nodiratime的相关文章

CentOS 7 Linux基本命令(11)深入理解Linux文件系统与日志

深入理解Linux文件系统与日志 一.inode和block概述 文件数据包括元信息与实际数据 元信息:文件的属性信息实际数据:文件内容 文件存储在硬盘上,硬盘最小存储单位是"扇区",每个扇区存储512字节 block(块) 连续的8个扇区组成一个block(4k)是文件存取的最小单位 inode(索引节点) 也叫i节点用于存储文件元信息 1.indoe的内容 inode包含文件的元信息 (1)文件的字节数(2)文件拥有者的User ID(3)文件的Group ID(4)文件的读.写.

理解Linux文件系统之inode

很少转发别人的文章,但是这篇写的太好了. 理解inode 作者: 阮一峰 inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础. 我觉得,理解inode,不仅有助于提高系统操作水平,还有助于体会Unix设计哲学,即如何把底层的复杂性抽象成一个简单概念,从而大大简化用户接口. 下面就是我的inode学习笔记,尽量保持简单. =================================== 理解inode 作者:阮一峰 一.inode是什么? 理解inode,要从文件储

Linux/Centos7系统管理之深入理解Linux文件系统与日志分析

前言: inode(文件节点)与block(数据块) 硬链接与软连接 恢复误删除的文件 (即rm-rf 的操作,可以先进行备份的操作,然后可以进行恢复ext4和xfs文件系统皆可) 日志文件的分类 用户日志与程序日志 一 :inode和block概述 1.1 概述 文件数据包括元信息与实际数据 文件存储在硬盘上,硬盘最小存储单位是"扇区",每个扇区储存512字节 block(块) 连续的八个扇区组成一个block,一个block单位是4k 是文件存取的最小单位 inode(索引节点)

深入理解Linux文件系统编程(二)

Linux文件系统编程实战 一.创建文件 <span style="font-size:14px;">#include<stdio.h> #include<stdlib.h> #include<sys/stat.h> #include<fcntl.h> //创建文件子函数 void creat_file(char *filename) { int fd; //系统调用描述文件的文件描述符(为非负数) if(fd=creat(f

深入理解Linux文件系统(一)

inode和block概述 文件数据包括元信息与实际数据 文件存储在硬盘上,硬盘最小储存单位是 "扇区",每个扇区储存512字节. block(块)中文译名为"索引节点",也叫i节点用于存储文件元信息 1.inode的内容 inode 包含很多的文件元信息,但不包含文件名,例如文件的字节数文件拥有着的UserID文件的GropuID文件的读.写.执行权限文件的时间戳 目录文件的结构目录也是一种文件目录文件的结构每一个inode都有一个号码,操作系统用inode号码来

Linux文件系统挂载

1. 基本知识 挂载:将额外文件系统与根文件系统某现存目录建立起关联关系,进而使得此目录作为其他文件访问入口的行为 卸载:解除此关联关系的过程 Mount Point: 把设备关联挂载点 挂载: mount命令 卸载: umount命令 可使用设备,也可使用挂载点来卸载 *注意*:挂载点下原有文件在挂载完后会被临时隐藏(所以挂载时尽可能使用空目录) 2. 挂载方法 mount DEVICE MOUNT_POINT mount [-fnrsvw] [-t vfstype] [-o options]

理论+实操:深入理解Linux文件系统与日志分析

前言: inode(文件节点)与block(数据块) 硬链接与软连接 恢复误删除的文件 (即rm-rf 的操作,可以先进行备份的操作,然后可以进行恢复ext4和xfs文件系统皆可) 日志文件的分类 用户日志与程序日志 一 :inode和block概述 1.1 概述 文件数据包括元信息与实际数据 文件存储在硬盘上,硬盘最小存储单位是"扇区",每个扇区储存512字节 block(块) 连续的八个扇区组成一个block,一个block单位是4k 是文件存取的最小单位 inode(索引节点)

深入理解Linux文件系统基础inode

转载自:http://www.ruanyifeng.com/blog/2011/12/inode.html 这篇文章对Inode的讲解比较透彻,好文章分享一下,一是收藏,二是让大家也可以一起学习(已懂的略过),对于一些重点的本人标红,并加些个人的补充. 一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是

深入理解Linux文件系统之inode

转载自:http://www.ruanyifeng.com/blog/2011/12/inode.html 这篇文章对Inode的讲解比较透彻,好文章分享一下,一是收藏,二是让大家也可以一起学习(已懂的略过),对于一些重点的本人标红,并加些个人的补充. 一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是