閱讀611 返回首頁    go 阿裏雲 go 技術社區[雲棲]


為什麼有時候讀取文件,atime不更新

在linux中,使用stat foo.txt 命令可以看到文件foo.txt的三個時間:

atime:access time,訪問時間

mtime:modify time,修改時間,文件內容有修改

ctime:change time,create time,改變時間,文件的索引節點發生變化,具體的情況有:1、文件內容有修改;2、文件權限有修改;3、inode變了;4、重命名(重命名不會導致inode改變)

PS:

1、如果用vi去修改某個文件,可能會發現這三個時間都被更新了,因為vi使用了臨時文件保存修改,在wq時替換了原來的文件,導致文件的inode被改變了,可以用ls -li驗證一下

2、如果想修改mtime,可以echo "hello world" >> foo.txt,注意ctime也會跟著改變

3、如果想僅僅修改ctime,可以chmod 644 foo.txt,mtime不會改變

4、為什麼沒說atime呢,不是想象中的那麼簡單的,後麵詳細分析

 

對於一個文件foo.txt

ls -l foo.txt 顯示的是mtime

ls -l -c foo.txt 顯示的是ctime

ls -l -u foo.txt 顯示的是atime

 

對於atime,當你以為cat foo.txt然後stat foo.txt能看到atime改變的話,很可能就會失望了,並不是每次atime都會改變的

atime和mount的參數以及內核有關:

 

       atime  Do  not  use noatime feature, then the inode access time is controlled
              by kernel defaults. See  also  the  description  for  strictatime  and
              relatime mount options.

       noatime
              Do  not update inode access times on this filesystem (e.g., for faster
              access on the news spool to speed up news servers).
       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.

       norelatime
              Do not use relatime feature. See also the strictatime mount option.

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

       nostrictatime
              Use the kernel's default behaviour for inode access time updates.

如果使用noatime,那麼atime就不會被更新,即使修改了文件內容

如果使用atime,采用內核默認行為,kernel2.6.30後就相當於使用了relatime

如果使用relatime,表示當atime比ctime或mtime更早,然後你又去讀取了文件,atime才會被更新為當前時間,kernel2.6.30後的默認行為;或者atime比現在早一天,那麼atime在文件讀取時會被更新

如果使用strictatime,atime在文件每次被讀取時,都能夠被更新

cat /proc/mounts可以看到我的服務器使用的是relatime參數: 

/dev/sdl1 /home ext4 rw,relatime,user_xattr,barrier=1,data=ordered 0 0

  

實驗環節:

noatime,可以看到不管是修改文件還是讀取文件,atime都不會變化,性能最好

shuyin.wsy@localhost:~$ sudo mount -t tmpfs -o noatime tmpfs /mnt
shuyin.wsy@localhost:~$ cd /mnt
shuyin.wsy@localhost:/mnt$ echo "hello world" >> foo.c
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 18h/24d Inode: 60855528    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:46:19.734162324 +0800 #最初值
Modify: 2016-04-11 17:46:19.734162324 +0800
Change: 2016-04-11 17:46:19.734162324 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ echo "hello world" >> foo.c
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 24              Blocks: 8          IO Block: 4096   regular file
Device: 18h/24d Inode: 60855528    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:46:19.734162324 +0800 #寫文件後,atime不變
Modify: 2016-04-11 17:46:38.142096924 +0800
Change: 2016-04-11 17:46:38.142096924 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cat foo.c
hello world
hello world
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 24              Blocks: 8          IO Block: 4096   regular file
Device: 18h/24d Inode: 60855528    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:46:19.734162324 +0800 #讀文件後,atime不變
Modify: 2016-04-11 17:46:38.142096924 +0800
Change: 2016-04-11 17:46:38.142096924 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cd
shuyin.wsy@localhost:~$ sudo umount /mnt

 

relatime,當atime早於或等於mtime/ctime時,才會被更新,2.6.30後的內核的默認行為,性能和atime更新折中的選擇
shuyin.wsy@localhost:~$ sudo mount -t tmpfs -o relatime tmpfs /mnt
shuyin.wsy@localhost:~$ cd /mnt
shuyin.wsy@localhost:/mnt$ echo "hello world" >> foo.c
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60855680    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:51:44.772736377 +0800 #最初值
Modify: 2016-04-11 17:51:44.772736377 +0800
Change: 2016-04-11 17:51:44.772736377 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cat foo.c > /dev/null
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60855680    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:51:56.036682655 +0800 #atime早於等於mtime/ctime,更新
Modify: 2016-04-11 17:51:44.772736377 +0800
Change: 2016-04-11 17:51:44.772736377 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cat foo.c > /dev/null
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60855680    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:51:56.036682655 +0800 #atime更晚時,不更新
Modify: 2016-04-11 17:51:44.772736377 +0800
Change: 2016-04-11 17:51:44.772736377 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ echo "hello world" >> foo.c
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 24              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60855680    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:51:56.036682655 +0800 #改變文件後,atime不更新
Modify: 2016-04-11 17:52:30.636519093 +0800
Change: 2016-04-11 17:52:30.636519093 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cat foo.c > /dev/null
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 24              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60855680    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 17:52:43.708457830 +0800 #讀取文件後,如果atime早於等於mtime/ctime,更新
Modify: 2016-04-11 17:52:30.636519093 +0800
Change: 2016-04-11 17:52:30.636519093 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cd
shuyin.wsy@localhost:~$ sudo umount /mnt

 

relatime,atime比現在早一天,那麼atime在文件讀取時會被更新,隨便找個老文件看看:

shuyin.wsy@localhost:~$ stat elfdiff.sh
  File: `elfdiff.sh'
  Size: 2067      	Blocks: 8          IO Block: 4096   regular file
Device: 8b1h/2225d	Inode: 103158619   Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-08 17:31:36.764025160 +0800 #atime比ctime和mtime晚,且距離現在超過一天
Modify: 2016-04-08 17:31:33.536040622 +0800
Change: 2016-04-08 17:31:33.580040411 +0800
 Birth: -
shuyin.wsy@localhost:~$ cat elfdiff.sh >/dev/null
shuyin.wsy@localhost:~$ stat elfdiff.sh
  File: `elfdiff.sh'
  Size: 2067      	Blocks: 8          IO Block: 4096   regular file
Device: 8b1h/2225d	Inode: 103158619   Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 22:12:31.984860509 +0800 #符合1天的條件,更新atime
Modify: 2016-04-08 17:31:33.536040622 +0800
Change: 2016-04-08 17:31:33.580040411 +0800
 Birth: -

 

strictatime,我們以為的那種atime,每次讀取都會更新,但是影響性能
shuyin.wsy@localhost:~$ sudo mount -t tmpfs -o strictatime tmpfs /mnt
shuyin.wsy@localhost:~$ cd /mnt
shuyin.wsy@localhost:/mnt$ echo "hello world" >> foo.c
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60853117    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 18:03:28.033857401 +0800 #最初值
Modify: 2016-04-11 18:03:28.033857401 +0800
Change: 2016-04-11 18:03:28.033857401 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cat foo.c >> /dev/null
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60853117    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 18:03:35.229824129 +0800 #隻要被讀取,atime就更新
Modify: 2016-04-11 18:03:28.033857401 +0800
Change: 2016-04-11 18:03:28.033857401 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cat foo.c >> /dev/null
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 12              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60853117    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 18:03:38.925807067 +0800 #隻要被讀取,atime就更新
Modify: 2016-04-11 18:03:28.033857401 +0800
Change: 2016-04-11 18:03:28.033857401 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ echo "hello world" >> foo.c
shuyin.wsy@localhost:/mnt$ stat foo.c
  File: `foo.c'
  Size: 24              Blocks: 8          IO Block: 4096   regular file
Device: 19h/25d Inode: 60853117    Links: 1
Access: (0644/-rw-r--r--)  Uid: (122712/shuyin.wsy)   Gid: (  100/   users)
Access: 2016-04-11 18:03:38.925807067 +0800 #改變文件,atime不更新
Modify: 2016-04-11 18:03:44.961779241 +0800
Change: 2016-04-11 18:03:44.961779241 +0800
 Birth: -
shuyin.wsy@localhost:/mnt$ cd
shuyin.wsy@localhost:~$ sudo umount /mnt

注意:當文件夾中的某個文件的時間改變時,文件夾本身的時間並不會受到影響

 
參考:

https://unix.stackexchange.com/questions/88840/atime-value-changing-only-once-after-file-creation

最後更新:2017-10-26 17:34:31

  上一篇:go  阿裏雲雙11活動擼福利攻略海外篇 新購5折,日本迪拜首惠
  下一篇:go  arm平台函數傳遞參數,反匯編實例分析