为什么 cat 命令查看文件不会修改 atime
今天在QQ群里有人问了一个问题:为什么用 cat 查看文件内容后不会修改它的 atime 呢?我试了一下,发现真的是这样的!例如下面这个例子,在 CentOS7 上执行
export LANG=C cd /tmp tmpfile=$(mktemp) echo "-------------------------------" >${tmpfile} stat ${tmpfile} |grep Access sleep 5 cat ${tmpfile} stat ${tmpfile} |grep Access
Access: (0600/-rw-------) Uid: ( 1000/lujun9972) Gid: ( 1000/lujun9972) Access: 2019-01-15 13:08:34.519887362 +0800 ------------------------------- Access: (0600/-rw-------) Uid: ( 1000/lujun9972) Gid: ( 1000/lujun9972) Access: 2019-01-15 13:08:34.519887362 +0800
这跟我们所熟知的 atime 的说法不一样啊。
经过一番探查,最终从 Criticism of atime 中发现了原因。
根据 Criticism of atime 的说法,读取文件要修改atime本身是一件很不合理的事情,因为要修改文件的atime就意味着要对磁盘进行写操作。 首先,在只读文件系统上你根本不可能修改文件的atime,更重要的是这增加了磁盘IO数量.
为了提高磁盘性能,我们可以完全禁止 atime 的修改(参看 mount 的 noatime 和 nodiratime 选项),但这会破坏 POSIX 兼容性,而且某些备份软件需要通过对比atime和mtime/ctime的时间来判断是否需要进行备份。
针对这个问题,Linux kernel 2.6.20 开始为 mount 引入了一个 relatime
选项,并从 2.6.30 开始这一选项默认是开启的。
当开启了 relatime
选项后,只有当 atime<mtime
或 atime<ctime
时,才会去更新 atime
. 通过这种方式,一方面可以大幅度减少 atime 引起的磁盘写操作,另一方面又保证了备份软件不受到影响,可谓非常精妙了。
下面这段关于 relatime 的说明取自 man mount
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 it 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 pro‐ vided by this option (unless noatime was specified), and the strictatime option is required to obtain traditional seman‐ tics. In addition, since Linux 2.6.30, the file's last access time is always updated if it is more than 1 day old.
另外,Linux kernel 4.0 开始引入了一个新选项 lazytime
,它可以让更新 atime 的操作缓存在内存中,然后当该文件有非时间相关的 IO 要写入时以其更新到磁盘中。 同时它也能设置超过多长时间后强制更新 atime,通过这种方式,lazytime
能做到在不影响性能的情况下保持 POSIX 兼容性。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论