Da bi se preselil v centralni distribucijski center, občasno opravljam razgovore v različnih velikih podjetjih, predvsem v Sankt Peterburgu in Moskvi, za položaj DevOps. Opazil sem, da veliko podjetij (veliko dobrih podjetij, na primer Yandex) postavlja dve podobni vprašanji:
- kaj je inode;
- iz katerih razlogov lahko pride do napake pri pisanju na disk (ali npr.: zakaj bi lahko zmanjkalo prostora na disku, bistvo je isto).
Kot se pogosto zgodi, sem bil prepričan, da to temo dobro poznam, a takoj ko sem začel razlagati, so se pokazale vrzeli v znanju. Da sistematiziram svoje znanje, zapolnim vrzeli in se ne spravljam več v zadrego, pišem ta članek, morda bo koristil še komu.
Začel bom od spodaj, tj. s trdega diska (zavrgli bomo bliskovne diske, SSD-je in druge sodobne stvari; na primer, razmislimo o katerem koli 20 ali 80 gigabajtu starem disku, saj je tam velikost bloka 512 bajtov).
Trdi disk ne ve, kako nasloviti svoj prostor bajt za bajtom, pogojno je razdeljen na bloke. Oštevilčenje blokov se začne z 0. (To se imenuje LBA, podrobnosti tukaj:
Kot je razvidno iz slike, sem bloke LBA označil kot raven HDD. Mimogrede, velikost bloka vašega diska lahko vidite takole:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512
Zgornja raven je particija, ena za celoten disk (spet zaradi poenostavitve). Najpogosteje se uporabljata dve vrsti označevanja particije: msdos in gpt. V skladu s tem je msdos stara oblika, ki podpira diske do 2 Tb, gpt pa je nova oblika, ki lahko naslovi do 1 zetabajt 512-bajtnih blokov. V našem primeru imamo particijo tipa msdos, kot je razvidno iz slike, se particija začne z blokom št. 1, za MBR pa se uporablja ničla.
V prvi particiji sem ustvaril datotečni sistem ext2, njegova privzeta velikost bloka je 4096 bajtov, kar se odraža tudi na sliki. Velikost bloka datotečnega sistema si lahko ogledate takole:
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
Parameter, ki ga potrebujemo, je "Velikost bloka".
Zdaj je zanimivo, kako prebrati datoteko /home/serp/testfile? Datoteka je sestavljena iz enega ali več blokov datotečnega sistema, v katerih so shranjeni njeni podatki. Če poznate ime datoteke, kako jo najti? Katere bloke naj preberem?
Tukaj inodi pridejo prav. Datotečni sistem ext2fs ima "tabelo", ki vsebuje informacije za vse inode. Število inodov v primeru ext2fs je nastavljeno pri ustvarjanju datotečnega sistema. Zahtevane številke pogledamo v parametru »Število inode« izhoda tune2fs, tj. imamo 65536 kosov. Inode vsebuje informacije, ki jih potrebujemo: seznam blokov datotečnega sistema za datoteko, ki jo iščemo. Kako najti številko inode za dano datoteko?
Ustrezno ime in številka inode sta v imeniku, imenik v ext2fs pa je posebna vrsta datoteke, tj. ima tudi svojo številko inode. Da bi prekinili ta začarani krog, je bila korenskemu imeniku dodeljena "fiksna" številka inode "2". Poglejmo vsebino inode številka 2:
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
Kot lahko vidite, je imenik, ki ga potrebujemo, v bloku številka 579. V njem bomo našli številko vozlišča za domačo mapo in tako naprej po verigi, dokler v imeniku serp ne vidimo številke vozlišča za zahtevano datoteko. Če nenadoma nekdo želi preveriti, ali je številka pravilna in ali so tam potrebni podatki, ni težko. Delamo:
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
V izhodu lahko preberete imena datotek v imeniku.
Tako pridem do glavnega vprašanja: "zaradi katerih razlogov lahko pride do napake pri snemanju?"
Seveda se bo to zgodilo, če v datotečnem sistemu ni več prostih blokov. Kaj je mogoče storiti v tem primeru? Poleg očitnega "izbriši vse nepotrebno" se morate spomniti, da v datotečnih sistemih ext2,3 in 4 obstaja nekaj takega kot "Rezervirano število blokov". Če pogledate zgornji seznam, imamo "13094" takih blokov. To so bloki, ki jih lahko piše samo root uporabnik. če pa morate hitro rešiti težavo, jih lahko kot začasno rešitev daste na voljo vsem, kar povzroči nekaj prostega prostora:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)
Tisti. privzeto imate 5% prostora na disku, ki ni na voljo za pisanje, glede na prostornino sodobnih diskov pa je to lahko na stotine gigabajtov.
Kaj bi drugega lahko bilo? Možno je tudi, da so prosti bloki, vendar ni več vozlišč. To se običajno zgodi, če imate v datotečnem sistemu veliko datotek, ki so manjše od velikosti bloka datotečnega sistema. Glede na to, da se 1 inode porabi za 1 datoteko ali imenik, skupaj pa imamo (za dani datotečni sistem) 65536 - je situacija več kot realna. To je jasno razvidno iz izhoda ukaza 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
Kot je jasno razvidno iz particije /var/www, se število prostih blokov v datotečnem sistemu in število prostih vozlišč zelo razlikujeta.
Če vam zmanjka inodov, vam ne bom povedal nobenih urokov, ker ... jih ni (če se motim, mi sporočite). Torej za particije, v katerih se množijo majhne datoteke, morate preudarno izbrati datotečni sistem. Inode btrfs se na primer ne morejo končati, ker Nove se po potrebi dinamično ustvarijo.
Vir: www.habr.com