该内容已被发布者删除 该内容被自由微信恢复
文章于 2019年1月15日 被检测为删除。
查看原文
被用户删除
其他

为什么 cat 命令查看文件不会修改 atime | Linux 中国

作者/Lujun9972 Linux中国 今天
首先,在只读文件系统上你根本不可能修改文件的 atime,更重要的是这增加了磁盘 IO 数量。
-- Lujun9972

致谢
转自 | lujun9972.github.io
作者 | Lujun9972

今天在 QQ 群里有人问了一个问题:

“为什么用 cat 查看文件内容后不会修改它的 atime 呢?”

我试了一下,发现真的是这样的!例如下面这个例子

  1. export LANG=C

  2. cd /tmp

  3. tmpfile=$(mktemp)

  4. echo "-------------------------------" >${tmpfile}

  5. stat ${tmpfile} |grep Access

  6. sleep 5

  7. cat ${tmpfile}

  8. stat ${tmpfile} |grep Access

  1. Access: (0600/-rw-------)  Uid: ( 1000/lujun9972)   Gid: ( 1000/lujun9972)

  2. Access: 2018-10-10 21:15:35.195471306 +0800

  3. -------------------------------

  4. Access: (0600/-rw-------)  Uid: ( 1000/lujun9972)   Gid: ( 1000/lujun9972)

  5. Access: 2018-10-10 21:15:40.198804743 +0800

这跟我们所熟知的 atime(访问时间)的说法不一样啊。

经过一番探查,最终从 Criticism of atime[1] 中发现了原因。

根据 Criticism of atime[1] 的说法,读取文件要修改 atime 本身是一件很不合理的事情,因为要修改文件的 atime 就意味着要对磁盘进行写操作。首先,在只读文件系统上你根本不可能修改文件的 atime,更重要的是这增加了磁盘 IO 数量。

为了提高磁盘性能,我们可以完全禁止 atime 的修改(参看 mount 的 --noatime 和 --nodiratime 选项),但这会破坏 POSIX 兼容性,而且某些备份软件需要通过对比 atime 和 mtime/ctime (修改时间/创建时间)的时间来判断是否需要进行备份。

针对这个问题,Linux 内核 2.6.20 开始为 mount 引入了一个 --relatime 选项,并从 2.6.30 开始这一选项默认是开启的。

当开启了 --relatime 选项后,只有当 atime < mtime 或 atime < ctime 时,才会去更新 atime。通过这种方式,一方面可以大幅度减少 atime 引起的磁盘写操作,另一方面又保证了备份软件不受到影响,可谓非常精妙了。

下面这段关于 --relatime 的说明取自 man mount

relatime
      相对于 inode 的修改或更改时间来更新它的访问时间。仅当先前的访问时间早于当前修改或更改时间时,才会更新访问时间。 (与 noatime 类似,但它不会破坏 mutt 或其他需要知道文件自上次修改后是否已被读取的应用程序)
      从 Linux 2.6.30 开始,内核默认使用此选项提供的行为(除非指定了 noatime),并且需要 strictatime 选项才能获得传统语义。 此外,自 Linux 2.6.30 起,如果文件的上次访问时间超过 1 天,则该文件的最后访问时间将始终更新。

另外,Linux 内核 4.0 开始引入了一个新选项 --lazytime。它可以让更新 atime 的操作缓存在内存中,然后当该文件有非时间相关的 IO 要写入时以其更新到磁盘中。同时它也能设置超过多长时间后强制更新 atime。通过这种方式,--lazytime 能做到在不影响性能的情况下保持 POSIX 兼容性。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存