關於索引節點的一些事情

為了調到中央配送中心,我會定期去多家大公司(主要是聖彼得堡和莫斯科)面試 DevOps 職位。 我注意到很多公司(很多優秀的公司,例如 Yandex)都會問兩個類似的問題:

  • 什麼是索引節點;
  • 什麼原因會導致磁碟寫入錯誤(或例如:為什麼可能會耗盡磁碟空間,本質是一樣的)。

正如經常發生的那樣,我確信我很了解這個主題,但當我開始解釋時,知識差距就變得明顯了。 為了系統化我的知識,填補空白,不再讓自己難堪,我寫這篇文章,也許對其他人有用。

我將從底部開始,即來自硬碟機(我們將丟棄快閃磁碟機、SSD 和其他現代裝置;例如,讓我們考慮任何 20 或 80 GB 的舊磁碟機,因為區塊大小為 512 位元組)。

硬碟不知道如何逐字節尋址其空間;它被有條件地劃分為區塊。 塊編號從0開始。(這稱為LBA,詳細資訊在這裡: ru.wikipedia.org/wiki/LBA)

關於索引節點的一些事情

從圖中可以看出,我將LBA區塊指定為HDD等級。 順便說一句,您可以這樣查看磁碟的區塊大小:

root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512

上面的一層是一個分割區,一個分割區用於整個磁碟(同樣是為了簡單起見)。 最常見的是使用兩種類型的分區標記:msdos 和 gpt。 因此,msdos 是一種舊格式,支援高達 2Tb 的磁碟,gpt 是一種新格式,能夠尋址高達 1 ZB 的 512 位元組區塊。 在我們的例子中,我們有一個 msdos 類型的分區,從圖中可以看出,該分區從 1 號區塊開始,而 MBR 使用零。

在第一個分區中我創建了一個ext2檔案系統,它的預設區塊大小是4096字節,這也在圖中有所體現。 您可以這樣查看檔案系統區塊大小:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          a600bf40-f660-41f6-a3e6-96c303995479
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              65536
Block count:              261888
Reserved block count:     13094
Free blocks:              257445
Free inodes:              65525
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      63
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Filesystem created:       Fri Aug  2 15:02:13 2019
Last mount time:          n/a
Last write time:          Fri Aug  2 15:02:14 2019
Mount count:              0
Maximum mount count:      -1
Last checked:             Fri Aug  2 15:02:13 2019
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Default directory hash:   half_md4
Directory Hash Seed:      c0155456-ad7d-421f-afd1-c898746ccd76

我們需要的參數是「區塊大小」。

現在有趣的部分是如何讀取 /home/serp/testfile 檔案? 文件由一個或多個儲存其資料的檔案系統區塊組成。 知道檔名,如何找到它? 我應該閱讀哪些塊?

這就是 inode 派上用場的地方。 ext2fs 檔案系統有一個“表”,其中包含所有 inode 的資訊。 ext2fs 的 inode 數量是在建立檔案系統時設定的。 我們查看tune2fs輸出的「Inode count」參數中所需的數字,即我們有 65536 件。 索引節點包含我們需要的資訊:我們正在尋找的檔案的檔案系統區塊清單。 如何查找給定檔案的索引節點號?

目錄中包含對應的名稱和inode號,ext2fs中的目錄是一種特殊類型的文件,即也有自己的索引節點號。 為了打破這個惡性循環,根目錄被分配了一個「固定」的inode編號「2」。 我們來看看2號inode的內容:

root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs:  stat <2>

Inode: 2   Type: directory    Mode:  0755   Flags: 0x0
Generation: 0    Version: 0x00000000:00000002
User:     0   Group:     0   Size: 4096
File ACL: 0    Directory ACL: 0
Links: 3   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Fri Aug  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fri Aug  2 15:02:14 2019
Size of extra inode fields: 28
BLOCKS:
(0):579
TOTAL: 1

如您所看到的,我們需要的目錄包含在區塊號 579 中。在其中我們將找到主資料夾的節點號,依此類推,直到在 serp 目錄中我們看到所請求檔案的節點號。 如果突然有人想檢查號碼是否正確,必要的資訊是否有,這並不困難。 我們的確是:

root@ubuntu:/# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 records in
1+0 records out
4096 bytes (4,1 kB) copied, 0,000184088 s, 22,3 MB/s
root@ubuntu:/# hexdump -c /home/serp/dd_image

在輸出中,您可以讀取目錄中檔案的名稱。

那麼我就來到了主要問題:“什麼原因會導致錄音錯誤?”

當然,如果檔案系統中沒有剩餘空閒區塊,就會發生這種情況。 在這種情況下可以做什麼? 除了明顯的「刪除任何不必要的東西」之外,您應該記住,在 ext2,3、4 和 13094 檔案系統中還有「保留區塊計數」之類的東西。 如果您查看上面的列表,我們有“XNUMX”這樣的區塊。 這些區塊只能由 root 使用者寫入。 但如果您需要快速解決問題,作為臨時解決方案,您可以將它們提供給所有人,從而產生一些可用空間:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)

那些。 預設情況下,您有 5% 的磁碟空間不可用於寫入,並且考慮到現代磁碟的容量,該空間可能達到數百 GB。

還能是什麼? 也有可能存在空閒區塊,但沒有更多節點。 如果檔案系統上有一堆小於檔案系統區塊大小的文件,通常會發生這種情況。 考慮到 1 個 inode 花費在 1 個檔案或目錄上,並且(對於給定的檔案系統)總共有 65536 個 inode - 這種情況非常現實。 這可以從 df 命令的輸出中清楚看出:

serp@ubuntu:~$ df -hi
Filesystem     Inodes IUsed IFree IUse% Mounted on
udev             493K   480  492K    1% /dev
tmpfs            493K   425  493K    1% /run
/dev/xvda1       512K  240K  273K   47% /
none             493K     2  493K    1% /sys/fs/cgroup
none             493K     2  493K    1% /run/lock
none             493K     1  493K    1% /run/shm
none             493K     2  493K    1% /run/user
/dev/xvdc1       320K  4,1K  316K    2% /var
/dev/xvdb1        64K   195   64K    1% /home
/dev/xvdh1       4,0M  3,1M  940K   78% /var/www
serp@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            2,0G  4,0K  2,0G   1% /dev
tmpfs           395M  620K  394M   1% /run
/dev/xvda1      7,8G  2,9G  4,6G  39% /
none            4,0K     0  4,0K   0% /sys/fs/cgroup
none            5,0M     0  5,0M   0% /run/lock
none            2,0G     0  2,0G   0% /run/shm
none            100M     0  100M   0% /run/user
/dev/xvdc1      4,8G  2,6G  2,0G  57% /var
/dev/xvdb1      990M  4,0M  919M   1% /home
/dev/xvdh1       63G   35G   25G  59% /var/www

從 /var/www 分區可以清楚看到,檔案系統中的空閒區塊數和空閒節點數差異很大。

如果你用完了索引節點,我不會告訴你任何咒語,因為...... 沒有(如果我錯了,請告訴我)。 因此,對於小檔案較多的分割區,應該明智地選擇檔案系統。 例如,btrfs inode 無法結束,因為如有必要,會動態建立新的。

來源: www.habr.com

添加評論