Periodiškai, norėdamas pereiti į Centrinį paskirstymo centrą, imu interviu įvairiose didelėse įmonėse, daugiausia Sankt Peterburge ir Maskvoje, siekdama DevOps pareigų. Pastebėjau, kad daugelis įmonių (daug gerų įmonių, pavyzdžiui, „Yandex“) užduoda du panašius klausimus:
- kas yra inode;
- dėl kokių priežasčių gali atsirasti disko rašymo klaida (arba pvz.: kodėl gali pritrūkti vietos diske, esmė ta pati).
Kaip dažnai nutinka, buvau tikra, kad šią temą išmanau gerai, bet vos pradėjus aiškintis, išryškėjo žinių spragos. Norėdamas susisteminti savo žinias, užpildyti spragas ir nebegėdinti savęs, rašau šį straipsnį, gal dar kam pravers.
Pradėsiu nuo apačios, t.y. iš kietojo disko (atmesime „flash drives“, SSD ir kitus šiuolaikinius dalykus; pavyzdžiui, panagrinėkime bet kurį 20 ar 80 GB seną diską, nes ten bloko dydis yra 512 baitų).
Kietasis diskas nežino, kaip adresuoti savo erdvę baitais po baito, jis sąlyginai suskirstytas į blokus. Blokų numeracija prasideda nuo 0. (Tai vadinama LBA, išsami informacija čia:
Kaip matyti iš paveikslo, LBA blokus paskyriau kaip HDD lygį. Beje, galite pamatyti, kokio dydžio blokas yra jūsų diske:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512
Aukščiau esantis lygis yra skaidinys, skirtas visam diskui (paprastumo dėlei). Dažniausiai naudojamas dviejų tipų skaidinio žymėjimas: msdos ir gpt. Atitinkamai, msdos yra senas formatas, palaikantis diskus iki 2Tb, o gpt yra naujas formatas, galintis adresuoti iki 1 zettabaito iš 512 baitų blokų. Mūsų atveju turime msdos tipo skaidinį, kaip matyti iš paveikslo, skaidinys prasideda bloku Nr. 1, o nulis naudojamas MBR.
Pirmajame skaidinyje sukūriau ext2 failų sistemą, jos numatytasis bloko dydis yra 4096 baitai, tai irgi atsispindi paveikslėlyje. Failų sistemos bloko dydį galite peržiūrėti taip:
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
Mums reikalingas parametras yra „Bloko dydis“.
Dabar įdomi dalis yra tai, kaip skaityti /home/serp/testfile failą? Failas susideda iš vieno ar daugiau failų sistemos blokų, kuriuose saugomi jo duomenys. Žinodami failo pavadinimą, kaip jį rasti? Kokius blokus turėčiau perskaityti?
Čia praverčia inodai. Ext2fs failų sistemoje yra "lentelė", kurioje yra informacija apie visus inodes. Inodų skaičius ext2fs atveju nustatomas kuriant failų sistemą. Tune2fs išvesties parametre “Inode count” žiūrime reikiamus skaičius, t.y. turime 65536 vnt. Inode yra mums reikalinga informacija: failų sistemos blokų sąrašas, skirtas mūsų ieškomam failui. Kaip rasti tam tikro failo inode numerį?
Atitinkamas pavadinimas ir inode numeris yra kataloge, o katalogas ext2fs yra specialus failo tipas, t.y. taip pat turi savo inodo numerį. Norėdami nutraukti šį užburtą ratą, šakniniam katalogui buvo priskirtas „fiksuotas“ indo numeris „2“. Pažvelkime į 2 inodo turinį:
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
Kaip matote, mums reikalingas katalogas yra bloke numeris 579. Jame rasime namų aplanko mazgo numerį ir taip toliau, kol serp kataloge pamatysime prašomo failo mazgo numerį. Jei staiga kas nors nori patikrinti, ar numeris teisingas ir ar yra reikiamos informacijos, tai nėra sunku. Mes darome:
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
Išvestyje galite perskaityti kataloge esančių failų pavadinimus.
Taigi prieinu prie pagrindinio klausimo: „dėl kokių priežasčių gali įvykti įrašymo klaida?
Natūralu, kad tai atsitiks, jei failų sistemoje neliks laisvų blokų. Ką galima padaryti šiuo atveju? Be akivaizdaus „ištrinkite viską, kas nereikalinga“, turėtumėte atsiminti, kad ext2,3, 4 ir 13094 failų sistemose yra toks dalykas kaip „Rezervuotų blokų skaičius“. Jei pažvelgsite į aukščiau esantį sąrašą, mes turime „XNUMX“ tokius blokus. Tai blokai, kuriuos gali įrašyti tik root naudotojas. bet jei jums reikia greitai išspręsti problemą, kaip laikiną sprendimą galite padaryti jas prieinamas visiems, todėl atsiras laisvos vietos:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)
Tie. pagal numatytuosius nustatymus turite 5% disko vietos, kuri nėra skirta rašymui, o atsižvelgiant į šiuolaikinių diskų tūrį, tai gali būti šimtai gigabaitų.
Kas dar galėtų būti? Taip pat gali būti, kad yra laisvų blokų, bet nebėra mazgų. Paprastai taip nutinka, jei failų sistemoje yra daug failų, kurie yra mažesni už failų sistemos bloko dydį. Atsižvelgiant į tai, kad 1 inode išleidžiama 1 failui ar katalogui, o iš viso turime (duotai failų sistemai) 65536 - situacija yra daugiau nei reali. Tai aiškiai matyti iš df komandos išvesties:
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
Kaip aiškiai matyti skaidinyje /var/www, laisvų blokų skaičius failų sistemoje ir laisvų mazgų skaičius labai skiriasi.
Jei pritrūks inodų, aš tau nesakysiu jokių burtų, nes... jų nėra (jei klystu, praneškite). Taigi skaidiniams, kuriuose dauginasi maži failai, rinkmenų sistemą reikėtų rinktis išmintingai. Pavyzdžiui, btrfs inodes negali baigtis, nes Jei reikia, dinamiškai kuriami nauji.
Šaltinis: www.habr.com