由mv命令引發的對inode的思考

於果alpha發表於2020-09-01

一場機器遷移引起的思考

最近團隊一臺機器老化了,準備做全量遷移,一不小心,就把100多個G的/data目錄放到了新機器的/data/data目錄下,上愁了,怎麼削減一層data目錄呢?難倒像Windows一樣剪下過來嗎?可是有100多個G啊?!抱著試試的心態,執行mv命令,沒想到系統瞬間就完成了。為什麼Linux可以這麼快速剪下呢?這一切都要從Linux對檔案的管理機制說起的。

inode是什麼

要想理解inode,就要從Linux的檔案儲存開始說起。

檔案儲存在硬碟上,硬碟上最小的儲存單位叫做“扇區”(sector),每一個扇區儲存512位元組。

作業系統讀取硬碟的時候,不會一個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取一個"塊"(block)。這種由多個扇區組成的"塊",是檔案存取的最小單位。"塊"的大小,最常見的是4KB,即連續八個 sector組成一個 block。

檔案資料都儲存在"塊"中,那麼很顯然,我們還必須找到一個地方儲存檔案的元資訊,比如檔案的建立者、檔案的建立日期、檔案的大小等等。這種儲存檔案元資訊的區域就叫做inode,中文譯名為"索引節點"。

每一個檔案都有對應的inode,裡面包含了與該檔案有關的一些資訊。

inode包含檔案的元資訊,具體來說有以下內容:

  • 檔案的位元組數。
  • 檔案擁有者的User ID。
  • 檔案的Group ID。
  • 檔案的讀、寫、執行許可權。
  • 檔案的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指檔案內容上一次變動的時間,atime指檔案上一次開啟的時間。
  • 連結數,即有多少檔名指向這個inode。
  • 檔案資料block的位置。

想要檢視檔案的inode資訊,可以通過stat命令。

每一個inode都有一個編號,就像上面,inode編號為5278,作業系統就靠inode編號來識別檔案。

強調一點,Linux不使用檔名,而是使用inode編號識別不同檔案。

對於使用者來說,通過檔名開啟了檔案;但是對於系統來說,首先,系統找到檔名對應的inode編號,通過這個編號獲取了inode資訊,再根據這個資訊,找到檔案資料所在的block,讀取資料並顯示。

目錄檔案

Linux中,目錄(directory)本身也是一種檔案。我們開啟目錄,其實就是開啟了目錄本身這個檔案。

目錄檔案的結構很簡單,就是一系列目錄項(dirent)的列表。每個目錄項包括兩部分:所包含檔案的檔名,以及該檔名對應的inode編號。也就是說,目錄檔案其實就是包含了檔名與inode編號的對映的集合。

通過ls -i命令可以檢視檔名和inode編號。

理解了上面這些,就能理解目錄的許可權。目錄檔案的讀許可權(r)和寫許可權(w),都是針對目錄檔案本身。由於目錄檔案內只有檔名和inode號碼,所以如果只有讀許可權,只能獲取檔名,無法獲取其他資訊,因為其他資訊都儲存在inode節點中,而讀取inode節點內的資訊需要目錄檔案的執行許可權(x)。

mv命令與inode

當執行mv命令後,構成這個檔案的實際內容,不管是inode還是硬碟資料,都沒有被轉移。被改變的,僅僅是目錄的對映(檔名與inode之間的對映)。

如果目標檔案和原檔案在同一個檔案系統,mv會在目錄對映表新建一行,刪除帶有原始檔名的原有目錄行。

如果目標檔案和原檔案不在同一個檔案系統,mv就相當於cp與rm命令的組合。

cp命令:分配一個沒有被使用的inode編號,在inode表中增加新專案,然後在目錄對映表中新增一行,關聯檔名與inode編號。

rm命令:遞減連結計數,釋放inode編號。然後把資料塊掛載到可用空間,再刪除目錄對映表中相關行。

我們可以看到,其中底層資料並沒有被刪除,只是被標記為了可用,當資料塊被另一個檔案利用時,原來的資料就會被覆蓋。

inode帶來的特殊現象(熱更新)

由於inode號碼與檔名分離,這種機制導致了一些Unix/Linux系統特有的現象。

有時,檔名包含特殊字元,無法正常刪除。這時,直接刪除inode節點,就能起到刪除檔案的作用。

移動檔案或重新命名檔案,只是改變檔名,不影響inode號碼。

開啟一個檔案以後,系統就以inode號碼來識別這個檔案,不再考慮檔名。因此,通常來說,系統無法從inode號碼得知檔名。

第3點使得軟體更新變得簡單,可以在不關閉軟體的情況下進行更新,不需要重啟。因為系統通過inode號碼,識別執行中的檔案,不通過檔名。更新的時候,新版檔案以同樣的檔名,生成一個新的inode,不會影響到執行中的檔案。等到下一次執行這個軟體的時候,檔名就自動指向新版檔案,舊版檔案的inode則被回收。

參考:

https://zh.wikipedia.org/wiki/Inode

https://www.cnblogs.com/peida/archive/2012/10/27/2743022.html

http://c.biancheng.net/cpp/html/2780.html

http://www.ruanyifeng.com/blog/2011/12/inode.html

相關文章