深入理解Linux磁盤文件系統之inode詳解

inode是什麼?

inode中文譯名為"索引節點"

文件儲存在硬盤上,硬盤的最小存儲單位叫做"扇區"(Sector)。每個扇區儲存512位元組(相當於0.5KB)。

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

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

inode的內容

inode包含文件的元信息,具體來說有以下內容:

* 文件的位元組數

* 文件擁有者的User ID

* 文件的Group ID

* 文件的讀、寫、執行權限

*文件的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指文件內容上一次變動的時間,atime指文件上一次打開的時間。

* 鏈接數,即有多少文件名指向這個inode

* 文件數據block的位置

示例1:

stat命令,查看某個文件的inode信息

[root@localhost mytest]# stat a.txt 

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

即指文件內容上一次變動的時間。如:echo aa >> a.sh 或vim a.sh 修改內容

atime : access time 訪問文件內容的時間

即指文件上一次查看文件的時間,如: cat a.sh

ctime指inode上一次文件屬性變動的時間,change time 。 比如: chmod +x a.sh

inode的大小

inode也會消耗硬盤空間,所以硬盤格式化的時候,操作系統自動將硬盤分成兩個區域。一個是數據區,存放文件數據;另一個是inode區(inode table),存放inode所包含的信息。

每個inode節點的大小,一般是128位元組或256位元組。inode節點的總數,在格式化時就給定,假定在一塊1GB的硬盤中,每個inode節點的大小為128位元組,每1KB就設置一個inode,那麼inode table的大小就會達到128MB,占整塊硬盤的12.8%。

inode號碼

每個inode都有一個號碼,操作系統用inode號碼來識別不同的文件。

Unix/Linux系統內部不使用文件名,而使用inode號碼來識別文件。對於系統來說,文件名只是inode號碼便於識別的別稱或者綽號。表面上,用戶通過文件名,打開文件。實際上,系統內部這個過程分成三步:首先,系統找到這個文件名對應的inode號碼;其次,通過inode號碼,獲取inode信息;最後,根據inode信息,找到文件數據所在的block,讀出數據。

示例2

使用ls -i命令,可以看到文件名對應的inode號碼

[root@localhost mytest]# ls -i


[root@localhost mytest]# ll -i

示例3

查看每個硬盤分區的inode總數和已經使用的數量,可以使用df命令


[root@localhost mytest]# df -i

目錄文件

Unix/Linux系統中,目錄(directory)也是一種文件。打開目錄,實際上就是打開目錄文件。

目錄文件的結構非常簡單,就是一系列目錄項的列表。每個目錄項,由兩部分組成:所包含文件的文件名,以及該文件名對應的inode號碼。


[root@localhost mytest]# ls -id /etc/

示例4

ls -i命令列出整個目錄文件,即文件名和inode號碼:

[root@localhost mytest]# ls -id /etc/

實戰

解決磁盤有空間但創建不了文件

場景

在一台配置較低的Linux服務器(內存、硬盤比較小)的/data分區內創建文件時,系統提示磁盤空間不足,用df -h命令查看了一下磁盤使用情況,發現/data分區只使用了80%,還有1.9G的剩餘空間,但是無法創建新的文件。當時使用的是root用戶。服務器沒有被黑。

[root@localhost mytest]# df -h

文件系統 容量 已用 可用 已用% 掛載點

/dev/sda3 10G 8.0G 1.9G 80% /

常識: 只要權限夠,磁盤上有空間一定可以創建文件。 這個是錯的。

排查過程

第一步:

用df -i

查看了一下/data所在的分區的索引節點(inode),發現已經用滿(IUsed=100%),導致系統無法創建新目錄和文件。

問題原因:

/data/cache目錄中存在數量非常多的小位元組緩存文件,佔用的Block不多,但是佔用了大量的inode。

[root@localhost mytest] # df -i 

文件系統 Inode 已用(I) 可用(I) 已用(I)% 掛載點

/dev/sda3 5242880 5242880 0 100% /

解決方案

第一種方案:

刪除/data/cache目錄中的部分文件,釋放出/data分區的一部分inode。

第二種方案 :

在/data備份好一些文件,然後刪除這些文件,釋放一些inode,然後創建一個文件夾/data/cache2。在cache2下掛載一個新分區: sda4 ,下次寫數據需要寫到新分區cache2目錄下。

inode分區完後,是不可以再增加的, inode總數是在格式化時定下來。

[root@localhost mytest] # mkfs.ext4 -I 500000000000 /dev/sda1 #可以指定大小

參數:

[-i bytes-per-inode] [-I inode-size]

擴展

inode的特殊作用

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

1. 有時,文件名包含特殊字符,無法正常刪除。這時,直接刪除inode節點,就能起到刪除文件的作用。

2. 移動文件或重命名文件,只是改變文件名,不影響inode號碼。

3. 打開一個文件以後,系統就以inode號碼來識別這個文件,不再考慮文件名。

因此,通常來說,系統無法從inode號碼得知文件名。