為了調到中央配送中心,我會定期去多家大公司(主要是聖彼得堡和莫斯科)面試 DevOps 職位。 我注意到很多公司(很多優秀的公司,例如 Yandex)都會問兩個類似的問題:
- 什麼是索引節點;
- 什麼原因會導致磁碟寫入錯誤(或例如:為什麼可能會耗盡磁碟空間,本質是一樣的)。
正如經常發生的那樣,我確信我很了解這個主題,但當我開始解釋時,知識差距就變得明顯了。 為了系統化我的知識,填補空白,不再讓自己難堪,我寫這篇文章,也許對其他人有用。
我將從底部開始,即來自硬碟機(我們將丟棄快閃磁碟機、SSD 和其他現代裝置;例如,讓我們考慮任何 20 或 80 GB 的舊磁碟機,因為區塊大小為 512 位元組)。
硬碟不知道如何逐字節尋址其空間;它被有條件地劃分為區塊。 塊編號從0開始。(這稱為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