Linux中atime,ctime與mtime的細節疑問總結

潇湘隐者發表於2024-04-29

在Linux檔案系統中,每一個檔案都有三個時間屬性,它們分別是atime,mtime,ctime,一般來說,atime比較好理解,但是很多時候,我們往往會混淆mtime和ctime這兩個時間屬性,或者搞不清楚兩者的區別。在展開介紹之前,我們先來看看如何檢視檔案的atime,mtime,ctime屬性。 下面簡單介紹一下:

檢視atime屬性

$ ls -lu

檢視mtime屬性

$ ls -l

檢視ctime屬性

$ ls -lc

具體可以檢視命令ls的幫助手冊(man ls)

-c     with -lt: sort by, and show, ctime (time of last modification of file status information); with -l: show ctime and
sort by name; otherwise: sort by ctime, newest first

-u with -lt: sort by, and show, access time; with -l: show access time and sort by name; otherwise: sort by access
time, newest first

使用stat命令檢視檔案的atime/mtime/ctime屬性

$ stat filename

下面是是一個構造的例子,如下所示:

[mysql@dbtest04 kerry]$ stat test.log
File: test.log
Size: 5 Blocks: 8 IO Block: 4096 regular file
Device: fd05h/64773d Inode: 1193621 Links: 1
Access: (0777/-rwxrwxrwx) Uid: ( 801/ mysql) Gid: ( 800/ mysql)
Access: 2024-04-29 11:03:21.616417230 +0800
Modify: 2024-04-29 11:01:56.599421770 +0800
Change: 2024-04-29 11:34:16.385318171 +0800
Birth: 2024-04-29 11:00:02.907427842 +0800
[mysql@dbtest04 kerry]$ ls -l test.log
-rwxrwxrwx 1 mysql mysql 5 Apr 29 11:01 test.log
[mysql@dbtest04 kerry]$ ls -lu test.log
-rwxrwxrwx 1 mysql mysql 5 Apr 29 11:03 test.log
[mysql@dbtest04 kerry]$ ls -lc test.log
-rwxrwxrwx 1 mysql mysql 5 Apr 29 11:34 test.log

那麼接下來,我們來看看atime/mtime/ctime三者的定義吧。

那麼我們接下來看看ctime與mtime的區別,一般來說,如果修改了檔案的許可權,屬主等屬性時,ctime會變化(mtime不會變化),修改檔案的內容時,mtime & ctime都會變化,也就是說如果mtime變化了的話,ctime一定會變化,而ctime變化,mtime不一定變化。 其實ctime表示最近一次metadata修改時間,這裡的修改有兩層意思:

  • 1 修改檔案/資料夾的metadata, 例如,檔案的訪問許可權(chmod)或檔案屬主。

  • 2 修改檔案內容

如果簡單一點的描述,就是mtime就是ctime的一個子集,ctime包含mtime,如果mtime變化了,ctime一定會變化。如下測試所示(這裡我們用root賬號來測試,方便修改檔案的屬主以及許可權。)

[root@dbtest04 ~]# touch test.log
[root@dbtest04 ~]# stat test.log
File: test.log
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 2837 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-04-29 12:03:01.741226024 +0800
Modify: 2024-04-29 12:03:01.741226024 +0800
Change: 2024-04-29 12:03:01.741226024 +0800
Birth: 2024-04-29 12:03:01.741226024 +0800
[root@dbtest04 ~]# chown mysql:mysql test.log
[root@dbtest04 ~]# stat test.log
File: test.log
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 2837 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 801/ mysql) Gid: ( 800/ mysql)
Access: 2024-04-29 12:03:01.741226024 +0800
Modify: 2024-04-29 12:03:01.741226024 +0800
Change: 2024-04-29 12:03:48.956223503 +0800
Birth: 2024-04-29 12:03:01.741226024 +0800
[root@dbtest04 ~]# chmod 755 test.log
[root@dbtest04 ~]# stat test.log
File: test.log
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 2837 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 801/ mysql) Gid: ( 800/ mysql)
Access: 2024-04-29 12:03:01.741226024 +0800
Modify: 2024-04-29 12:03:01.741226024 +0800
Change: 2024-04-29 12:04:22.778221696 +0800
Birth: 2024-04-29 12:03:01.741226024 +0800
[root@dbtest04 ~]# echo "it is test" > test.log
[root@dbtest04 ~]# stat test.log
File: test.log
Size: 11 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 2837 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 801/ mysql) Gid: ( 800/ mysql)
Access: 2024-04-29 12:03:01.741226024 +0800
Modify: 2024-04-29 12:04:57.245219856 +0800
Change: 2024-04-29 12:04:57.245219856 +0800
Birth: 2024-04-29 12:03:01.741226024 +0800

不知道你注意到沒有,往檔案寫入內容的時候,atime居然沒有變化,這裡為了驗證,我們再做一次測試,如下截圖所示

如上截圖所示,我們往檔案中寫入內容,atime居然沒有變化,其實你使用more、cat命令訪問檔案,檔案的atime也沒有變化,Why?Why?Why?直到我看到這篇文章"檔案atime未變問題的研究"[1](下面部分內容來自這篇文章):

在kernel版本2.6.30之前,Linux的核心開發人員針對Ext3/Ext4檔案系統的效能進行了討論,其中包括atime。在Ksernel 2.6.30之前,檔案系統中預設會及時的更新atime,這樣會帶來兩個問題:

  1. 系統中大量的檔案訪問,將atime寫入到磁碟中,消耗時間,從而降低效能

  2. 這樣的操作也會消耗電能

在Linux上執行的,很少的應用程式需要獲取精確的atime時間,並且Linux核心開發人員從Ext3/Ext4檔案系統的效能角度出發,決定在2.6.30版本的核心中修改atime的更新方式,只有在以下三種情況之一才會更新atime:

  • (1) 如果將分割槽mount的掛載的時候指定採用非relatime方式(預設採用relatime方式),如strictatime.

補充:在OS啟動的時候,將各個分割槽掛載到不同的目錄,在掛載(mount)的引數中採用strictatime,表明及時更新atime。在2.6.30之後mount新增了”relatime”和”strictatime”兩個選項,詳細的可以透過”man mount”檢視。

  • (2) atime小於ctime或者小於mtime的時候

  • (3) 本次的access time和上次的atime超過24個小時

這種做法避免了頻繁的更新atime,提高了檔案系統的效能。果然做Linux核心的大牛無不從每一個細節抓起呢,敬佩。

更多的詳細資訊,我們可以參考這篇文章[2],這裡額外展開一下,ls 和 stat命令並不會修改檔案的atime屬性,如下測試所示

[mysql@dbtest04 kerry]$ rm kerry.log
[mysql@dbtest04 kerry]$ touch kerry.log
[mysql@dbtest04 kerry]$ stat kerry.log
File: kerry.log
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd05h/64773d Inode: 1193622 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 801/ mysql) Gid: ( 800/ mysql)
Access: 2024-04-29 15:35:58.084543673 +0800
Modify: 2024-04-29 15:35:58.084543673 +0800
Change: 2024-04-29 15:35:58.084543673 +0800
Birth: 2024-04-29 15:35:58.084543673 +0800
[mysql@dbtest04 kerry]$ ls kerry.log
kerry.log
[mysql@dbtest04 kerry]$ stat kerry.log
File: kerry.log
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd05h/64773d Inode: 1193622 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 801/ mysql) Gid: ( 800/ mysql)
Access: 2024-04-29 15:35:58.084543673 +0800
Modify: 2024-04-29 15:35:58.084543673 +0800
Change: 2024-04-29 15:35:58.084543673 +0800
Birth: 2024-04-29 15:35:58.084543673 +0800

參考資料

[1]

1: https://blog.csdn.net/cjf_iceking/article/details/11988525

[2]

2: http://www.h-online.com/open/news/item/Kernel-Log-What-s-coming-in-2-6-30-File-systems-New-and-revamped-file-systems-741319.html

相關文章